DE LA RECHERCHE SCIENTIFIQUE
Université de Jendouba
Institut Supérieur d’Informatique de Kef
Réalisé par
LABIDI Ali
Président : …………………
Rapporteur : ……………
LABIDI Ali
Remerciements
Je tiens à remercier mon encadrant Mr Maher Heni qui, par son expérience,
son don d’écoute et sa tolérance, a guidé mon activité tout en préservant mon
esprit d’initiative, durant toute la période de construction du projet.
Le désabonnement des clients est une préoccupation considérable dans les secteurs de
services où les services sont très compétitifs. D'autre part, la prévision des clients susceptibles
de quitter l'entreprise représentera une source de revenus supplémentaire potentiellement
importante si cela est fait à un stade précoce. Des nombreuses recherches ont confirmé que la
technologie d’apprentissage automatique est très efficace pour prévoir cette situation. Cette
technique est appliquée en tirant parti des données précédentes.
Dans ce projet, nous nous sommes concentrés sur l’évaluation et l’analyse des performances
d’un ensemble de méthodes et d’algorithmes d’apprentissage automatique permettant de
prévoir le désabonnement des clients dans des entreprises de télécommunications. Dans un
premier abord nous présenterons des fondements, à savoir l’analyse de données, Machine
learning et Prédiction. Par la suite, nous vous présenterons la problématique et qui ont la
vocation d’être résolues.
Passant par la suite à notre choix une solution technologique, des modèles de prédiction
développé par python à base de machine learning. L’output généré fera objet d’analyse et
d’interprétation pour démontrer l’utilité de l’analyse de données dans la prédiction de faits
dans le domaine de télécommunication.
1
Chapitre 1
Contexte du projet
Chapitre 1 : Contexte du projet
1.1. Introduction
Dans ce premier chapitre, nous allons aborder les concepts clés relatifs de notre sujet à
savoir : La prédiction du churn, vers l’analyse des données et en finissant par l’intervention de
la machine Learning dans la prédiction. Nous allons définir leurs différentes notions ainsi que
leurs domaines d’application.
2
Chapitre 1 : Contexte du projet
La dynamique concurrentielle peut elle aussi influer sur les risques de désabonnement,
comme c’est le cas dans le secteur de télécommunication, où elle représente un défi de taille.
Les entreprises spécialisées dans la gestion des données sont donc de plus en plus nombreuses
à proposer des outils de prédiction. Ceux-ci permettent, à partir des données clients, de
déterminer ceux qui ont la plus forte probabilité de désabonnement.
Prédire le désabonnement permet d’adapter sa stratégie de fidélisation, et d’épargner ainsi aux
entreprises les efforts déployés pour retenir les clients.
S’il est difficile d’empêcher les clients de quitter une plateforme donnée, on peut en
revanche identifier les causes des désabonnements précédents et tenter d’y remédier. Plusieurs
outils permettent de collecter et de retrouver ces données :
Le sondage en phase de désabonnement, qui doit proposer plusieurs choix de réponse
au client.
Des outils de prédiction et d’analyse des données liées au désabonnement.
Une stratégie de suivi afin de prévenir le départ des clients, notamment à travers des
campagnes personnalisées et des enquêtes.
Notons que l’entreprise elle-même peut être à l’origine de la perte du client, dans le cas d’un
défaut de paiement par exemple.
Une fois les causes de désabonnement décelées et classées, il est ensuite possible de rectifier
le tir en mettant en place des actions destinées à réduire la perte de clients. Parmi ces actions,
on peut citer :
Cibler la bonne audience, en étudiant notamment les besoins de vos prospects.
3
Chapitre 1 : Contexte du projet
L’objectif étant d’éviter autant que possible le désabonnement des clients. Lorsque, en
dépit des précautions prises, le désabonnement survient, l’entreprise doit prendre des mesures
visant à retenir ses clients et déployer une stratégie anti-churn efficace pour éviter de perdre
plus de clients.
Il s’agit donc d’éviter le désabonnement et de limiter le risque de perte quand celui-ci s’avère
inévitable. Une manœuvre anti-churn efficace prend en compte les grands comptes : clients
les plus rentables, influenceurs et prescripteurs
4
Chapitre 1 : Contexte du projet
Gérer le risque de désabonnement et la perte de ces clients passe généralement par trois
mesures différentes :
Lorsqu’une stratégie anti-churn est assez prévoyante et efficace, les revenus de l’entreprise
s’en ressentent immédiatement. Le fait d’avoir mesuré le risque de désabonnement permet par
conséquent de mesurer immédiatement et avec précision le résultat en termes de revenus. Il
faut donc ajouter aux actions de conquête et de fidélisation des actions de reconquête, telles
que des campagnes ad-hoc ou un enrichissement du programme de fidélisation. C’est le trio
gagnant pour apprendre de ses erreurs, rectifier le tir, et soutenir la prospérité de l’entreprise.
L'étude met en exergue un cycle de six étapes clés dans l'élaboration de solutions prédictives
grâce au Big data : [2]
5
Chapitre 1 : Contexte du projet
Pour manipuler les deux premiers étapes d’études ont besoin donc de data mining que nous
allons aborder maintenant.
Le Data Mining est une composante essentielle des technologies Big Data et des
techniques d’analyse de données volumineuses. Il s’agit là de la source des Big Data
Analytics, des analyses prédictives et de l’exploitation des données. [B1]
Comme dans toute exploitation, le but recherché est de pouvoir extraire de la richesse. Ici, la
richesse est la connaissance de l'entreprise. Fort du constat qu'il existe au sein des bases de
données de chaque entreprise une ressource de données cachées et surtout inexploitée, le data
Mining permet de faire les apparaître, et cela grâce à un certain nombre de techniques
spécifiques. Nous appellerons data Mining l'ensemble des techniques qui permettent de
transformer les données en connaissances. Le périmètre d'exploitation du data Mining ne se
limite pas à l'exploitation des Data warehouse. Il veut d'être capable d'exploiter toutes bases
6
Chapitre 1 : Contexte du projet
de données contenant de grandes quantités de données telles que des bases relationnelles, des
entrepôts de données mais également des sources plus ou moins structurées comme internet.
Le data Mining est un processus itératif qui met en œuvre un ensemble de techniques
hétéroclites tel que le data warehouse, de la statistique, de l'intelligence artificielle, de
l'analyse des données et des interfaces de communication homme - machine. Le résultat du
data mining peut se présenter sous différent format : texte plat, tableau, graphique...[3]
Le data Mining peut explorer les données pour découvrir un lien "inconnu". Quand le
décideur n’a pas d'hypothèse ou d'idée sur un fait précis, il peut demander au système de
proposer des associations ou des corrélations qui pourront aboutir à une explication. Il est
utopique de croire que le data Mining pourrait remplacer la réflexion humaine. Le data
Mining ne doit être vu et utiliser uniquement en tant qu'aide à la prise de décision. Par contre,
7
Chapitre 1 : Contexte du projet
1.5. Conclusion
Dans ce premier chapitre, nous avons traité les concepts clés de notre sujet qui sont
respectivement Prédiction du churn, l’analyse des données et l’intervention de la machine
Learning. Nous avons aussi dégagé le lien entre ces disciplines qui convergent ensemble vers la
connaissance et la maîtrise d’un pouvoir indéniable de l’ère actuelle.
8
Chapitre 2
Etat de l’art
Chapitre 2 : Etat de l’art
2.1. Introduction
Rien d’étonnant lorsque l’on sait que plusieurs recherches prouvent qu’il coûte presque
5 à 25 fois plus cher d’aller chercher de nouveaux clients que de fidéliser ses clients existants.
Par conséquent, Les entreprises mettent en place des moyens colossaux pour atténuer le
désabonnement et maintenir leurs clientèles. Cette problématique est importante dans
l’industrie des fournisseurs de service comme par exemple Vidéotron, Netflix, les opérateurs
de télécommunications, etc…
Dans ce chapitre, nous présentons le problème de désabonnement ainsi que les différents
paradigmes utilisés par les industries pour remédier à cette problématique.
Des nombreuses recherches ont confirmé que la technologie d’apprentissage automatique est
très efficace pour prévoir cette situation. Cette technique est appliquée en tirant parti des
données précédentes.
9
Chapitre 2 : Etat de l’art
traditionnelle, utilisent des indicateurs généralisés pour mesurer le désabonnement [5]. Ces
indicateurs présentent de l’information agrégée sur des données passées, par exemple le
nombre de désabonnement du mois dernier.
Le problème, c’est que les entreprises utilisant ces techniques sont continuellement dans une
approche réactive pour résoudre leur problème de désabonnement. Autrement dit, elles ont
toujours un temps de retard.
La bonne nouvelle c’est que l’apprentissage machine permet maintenant à ces entreprises de
développer des modèles prédictifs pour identifier les clients à risque avant qu’ils ne se
désabonnent. Plutôt que d’être réactives, les entreprises ont désormais la chance d’adopter une
approche proactive. Il s’agit là d’un véritable changement de paradigme.
𝑇𝑎𝑢𝑥 𝑑𝑒 𝑑é𝑠𝑎𝑏𝑜𝑛𝑛𝑒𝑚𝑒𝑛𝑡=
10
Chapitre 2 : Etat de l’art
Le taux de désabonnement est important pour les entreprises puisqu’il est l’indicateur par
excellence de la satisfaction de leurs clients. S’ils sont frustrés et insatisfaits, ces indicateurs
sont essentiels pour mesurer les effets des actions marketing : sont-elles bénéfiques?
L’entreprise est-elle sur la voie de la rentabilité?
L’image ci-dessus présente les efforts marketing dans une approche BI traditionnelle. La
question principale est : « Maintenant que le client s’est désabonné, comment nous pouvons le
regagner ? »
Les stratégies de rétention traditionnelles comportent des éléments permettant aux entreprises
d’apprendre de leurs erreurs et tenter de regagner leurs clientèles.
Des nombreuses entreprises vont s’adresser aux clients désabonnés pour comprendre leur
motif et améliorer leurs services en fonction de leurs commentaires.
11
Chapitre 2 : Etat de l’art
12
Chapitre 2 : Etat de l’art
averties que quelque chose ne va pas, dans le meilleur des cas, le mois suivant le
désabonnement de leurs clients… mode réactif plutôt que proactif.
13
Chapitre 2 : Etat de l’art
14
Chapitre 2 : Etat de l’art
80% des données historiques sont utilisées pour entraîner le modèle statistique. Le 20%
restant est utilisé pour valider si le modèle donne les bons résultats. Ces données de test sont
vues comme des données nouvelles puisqu’elles n’ont pas été utilisées dans la phase
d’entrainement de l’algorithme.
Obtenir les prédictions : Une fois le modèle statistique testé et validé, vous serez en
mesure d’identifier vos clients à risques. Un modèle permet non seulement de
découvrir ces clients mais également les caractéristiques ayant une influence sur le
désabonnement.
Passer à l’action : Une fois que vous avez en main les probabilités que vos clients se
désabonnent vous devez mettre en place des actions concrètes.
Les prédictions ne servent à rien si elles ne sont pas suivies par des actions concrètes.
Examinez leur profil, identifiez leurs caractéristiques, analysez les interactions passées avec
vos services et produits. Communiquez vos plus récentes offres et services susceptibles de
combler leurs besoins. bien que s’assurer de leur proposer des solutions adaptées à leurs
besoins, de ce fait vous créerez un sentiment d’appartenance chez vos clients et cela les liera à
votre entreprise.
15
Chapitre 2 : Etat de l’art
2.8. Conclusion
Dans ce chapitre nous avons présenté l’état de l’art dans le domaine de prédiction des
taux de désabonnement. Nous avons positionné notre problème et nous avons décrit le grand
titre de notre recherche.
16
Chapitre 3
Analyse Prédictive
Chapitre 3 : Analyse Prédictive
3.1. Introduction
Pour développer un modèle prédictif qui permet de résoudre le probélme de
désabonnement de clients, il faut collecter les données utiles, nettoyer ces données,
sélectionner les variables et finir par la modélisation. Ce qui fait appel aux deux intervenants
principaux qui sont le data mining et la machine learning,
17
Chapitre 3 : Analyse Prédictive
Les fonctions supervisées : elles travaillent avec une cible, permettent de prédire
une valeur. La modélisation et la décision se fondent sur l'observation du passé.
Les fonctions supervisées sont aussi désignées par les termes fonctions distinctes
ou fonctions prédictives.
Les fonctions non supervisées : elles détectent des relations, des analogies ou
concordances entre les données. Ces fonctions n'utilisent aucune cible. Ces
fonctions s'appuient sur le clustering hiérarchique, les centres mobiles, les règles
d'association, etc. pour extraire des similitudes dans les données. Les fonctions
non supervisées sont aussi désignées par les termes fonctions indirectes ou
fonctions descriptives.
Évaluation des modèles : l'évaluation du (où) des modèle(s) est une étape importante
qui permet de vérifier que les questions posées lors de l'étape 1 ont bien trouvé une
réponse fiable. Une fois les modèles construits, il peut s'avérer nécessaire de revoir les
18
Chapitre 3 : Analyse Prédictive
19
Chapitre 3 : Analyse Prédictive
20
Chapitre 3 : Analyse Prédictive
Nous avons extrait des matrices et des vecteurs de type « NumPy » pour les analyses
subséquentes avec « scikit-learn ». Une explication de toute les packages utilisées et leurs
utilités sera détaillée dans le chapitre suivant.
Les analyses prédictives consistent à utiliser les données et les techniques de Machine
Learning pour prédire les probabilités des tendances et des résultats utiles pour les
entreprises, en se basant sur l’historique des données. Ces analyses rassemblent plusieurs
technologies et disciplines comme les analyses statistiques, le data mining, la modélisation
prédictive et la Machine Learning pour prédire le futur des entreprises.
Dans la suite de chapitre, nous présentons les différents modèles de prédiction et les
différents outils de sélection et de création de variables important.
21
Chapitre 3 : Analyse Prédictive
Le processus de modélisation implique l’exécution d’un algorithme sur des données à des fins
de prédiction car le processus est itératif, il forme le modèle qui fournit les connaissances les
plus appropriées pour la réalisation des tâches. Voici quelques étapes de la modélisation
analytique.
Collecte de données et nettoyage : Rassemblez les données de toutes les sources pour
extraire les informations nécessaires en nettoyant les opérations pour supprimer les
données bruitées afin que la prédiction puisse être précise.
Inférences / évaluation: Pour faire des déductions, il faut effectuer une analyse de
cluster et créer des groupes de données.
22
Chapitre 3 : Analyse Prédictive
La bibliothèque « scikit-learn » fournit la classe « SelectKBest » qui peut être utilisée avec une
suite de différents tests statistiques pour sélectionner un nombre spécifique de fonctionnalités.
On utilise dans notre cas le test statistique chi-carré (chi²) pour les caractéristiques non
négatives afin de sélectionner les meilleures caractéristiques du jeu de données de prévision du
désabonnement des clients.
La corrélation indique comment les entités sont liées les unes aux autres ou à la variable
cible. De même elle peut être positive (augmentation d'une valeur d'entité augmente la valeur
de la variable cible) ou négative (augmentation d'une valeur d'entité diminue la valeur de la
variable cible). Nous allons tracer la carte thermique des entités corrélées à l'aide de la
bibliothèque « Seaborn ».
23
Chapitre 3 : Analyse Prédictive
Régression logistique
Synthetic Minority Oversampling TEchnique (SMOTE)
Recursive Feature Elimination (RFE)
Decision Tree
A random forest
Gaussian Naive Bayes
Support Vector Machine
LightGBMClassifier
XGBoost Classifier
24
Chapitre 3 : Analyse Prédictive
Les arbres de décision sont des algorithmes d'apprentissage supervisé utilisés pour les
tâches de classification, de régression et de prédiction dans lesquelles nous allons nous
concentrer sur la prédiction. Des arbres de décision sont attribués aux algorithmes
d'apprentissage basés sur l'information qui utilisent différentes mesures du gain d'information
pour l'apprentissage. Nous pouvons utiliser des arbres de décision pour les problèmes pour
lesquels nous disposons d’éléments d’entrée et de cibles continus mais également
catégoriels. L'idée principale des arbres de décision est de rechercher les entités descriptives
contenant le plus "d'informations" concernant l'entité cible, puis de scinder le jeu de données
en fonction de la valeur de ces entités, de sorte que les valeurs des entités cibles pour les sous-
jeux de données résultants soient aussi pures que possible. Ce processus de recherche de la
fonctionnalité est effectué jusqu'à ce que nous remplissions un critère d'arrêt, où nous nous
retrouvons finalement dans des nœuds terminaux. Les nœuds terminaux contiennent les
prédictions que nous allons effectuer pour les nouvelles instances de requête présentées à
notre modèle formé. Cela est possible car le modèle a en quelque sorte appris la structure
sous-jacente des données d'apprentissage et peut donc, compte tenu de certaines hypothèses,
effectuer des prédictions sur la valeur de caractéristique cible (classe) d'instances de requête
invisibles. Un arbre de décision contient principalement un nœud racine, des nœuds
intérieurs et des nœuds feuille qui sont ensuite connectés par des branches. [8]
25
Chapitre 3 : Analyse Prédictive
En principe, les arbres de décision peuvent être utilisés pour prédire la fonctionnalité cible
d'une instance de requête inconnue en construisant un modèle basé sur des données existantes
pour lesquelles les valeurs de fonctionnalité cible sont connues (apprentissage supervisé). De
plus, nous savons que ce modèle peut effectuer des prédictions pour des instances de requête
inconnues, car il modélise la relation entre les fonctionnalités descriptives connues et la
fonctionnalité de cible connue. De plus, nous savons que pour former un modèle d'arbre de
décision, nous avons besoin d'un jeu de données composé d'un certain nombre d'exemples de
formation caractérisés par un certain nombre de caractéristiques descriptives et une
fonctionnalité cible. [8]
La prédicteur de forêt aléatoire crée un ensemble d'arbres de décision à partir d'un sous-
ensemble sélectionné d'un ensemble d'apprentissage. Il regroupe ensuite les votes de
différents arbres de décision pour décider de la classe finale de l'objet à tester. Les paramètres
de base du prédicteur de forêt aléatoire peuvent être le nombre total d’arbres à générer et les
paramètres associés aux arbres de décision tels que la division minimale, les critères de
division, etc…
Avant de pouvoir appliquer les prédicteurs, nous devons nettoyer les données. Le nettoyage
implique la suppression des mots vides, l'extraction des mots les plus courants du texte, etc…
26
Chapitre 3 : Analyse Prédictive
Dans un problème de classification, notre hypothèse (h) peut être la classe à affecter à une
nouvelle instance de données (d).
27
Chapitre 3 : Analyse Prédictive
L’un des moyens les plus simples de sélectionner l’hypothèse la plus probable compte tenu
des données dont nous disposons et que nous pouvons utiliser comme connaissance préalable
du problème. Le théorème de Bayes fournit un moyen de calculer la probabilité d'une
hypothèse compte tenu de nos connaissances antérieures.
Le théorème de Bayes est formulé comme suit:
P (h | d) = (P (d | h) * P (h)) / P (d)
Où
P (h | d) est la probabilité de l'hypothèse h étant donnée les données d.
P (d | h) est la probabilité pour les données d étant donné que l'hypothèse h était vraie.
P (h) est la probabilité que l'hypothèse h soit vraie (quelles que soient les données).
P (d) est la probabilité des données (quelle que soit l'hypothèse).
Il existe également les Bayes naïfs multinomiaux et les Bayes naïfs de Bernoulli. Nous
choisissons le naïf gaussien parce que c'est le plus simple et le plus populaire.
28
Chapitre 3 : Analyse Prédictive
Les SVM peuvent être utilisés aussi bien pour la prédiction que pour la classification. Elles
avaient été réalisées dans certains domaines, à savoir la popularité manuscrite à chiffres, la
reconnaissance d'objets et l'identité du haut-parleur, en plus des vérifications de prédiction des
séries chronologiques de référence.
29
Chapitre 3 : Analyse Prédictive
feuille dans Light GBM, l’algorithme feuille-feuille peut réduire plus de pertes que
l’algorithme niveau-résultats et permet donc d’obtenir une bien meilleure précision que l’un
des algorithmes de renforcement existants ne permet que rarement. En outre, il est
étonnamment très rapide, d’où le mot « lumière ».
LGBM utilise la division par feuille sur la division par profondeur, ce qui lui permet de
converger beaucoup plus rapidement.
30
Chapitre 3 : Analyse Prédictive
31
Chapitre 3 : Analyse Prédictive
Exemple :
Si un système de prédiction a été formé pour faire la distinction entre « churn » et « not-
churn », une matrice de confusion résumera les résultats du test de l'algorithme en vue d'une
inspection plus poussée. En supposant un échantillon de 13 clients « 8 churn » et « 5 not-
churn » la matrice de confusion résultante pourrait ressembler au tableau ci-dessous:
Classe actuelle
Churn Not-churn
Classe prédite
Not-churn 3 faux négatifs 3 vrais négatifs
32
Chapitre 3 : Analyse Prédictive
mesure. En fait, cela signifie que le résultat est réciproque. Il prédit que les 0 sont 1 et les 1 que
les 0. Et lorsque l’AUC est de 0,5. cela signifie que le modèle n’a aucune capacité de
séparation de classe.
Un système avec un rappel élevé mais une faible précision renvoie de nombreux résultats, mais
la plupart de ses étiquettes prédites sont incorrectes par rapport aux étiquettes de formation. Un
système avec une précision élevée mais un faible rappel est tout à fait le contraire: il ne donne
que très peu de résultats, mais la plupart de ses étiquettes prédites sont correctes par rapport
aux étiquettes de formation. Un système idéal avec une grande précision et un rappel élevé
renverra de nombreux résultats, tous étiquetés correctement.
Précision (P) est défini comme le nombre de vrais positifs (Tp) sur le nombre de vrais positifs
plus le nombre de faux positifs (Fp).
P=Tp/(Tp+Fp)
Rappel (R) est défini comme le nombre de vrais positifs (Tp) sur le nombre de vrais positifs
plus le nombre de faux négatifs (Fn).
R=Tp/(Tp+Fn)
33
Chapitre 3 : Analyse Prédictive
3.6. Conclusion
Dans ce chapitre, on a montré que les outils intelligents (Data Mining, Machine
Learning) revêtent, de plus en plus, une importance cruciale dans tous les domaines qui
rendent des services aux clients et en particulier nous mentionnons les opérateurs de
télécommunication.
34
Chapitre 4
4.1. Introduction
Dans ce chapitre, nous présenterons les résultats obtenus suite aux différentes analyses
effectuées sur la base de données. Tout d’abord, une analyse descriptive des variables
prédictives les plus importantes donnera un aperçu global sur les désabonnements des clients.
En deuxième lieu, une analyse des résultats obtenus par le modèle développé permettra de
répondre aux objectifs de recherche que se fixe ce mémoire.
Nous allons détailler dans ce qui suit les différentes manipulations effectuées :
Analyse de données exploratoire
Prétraitement de données
Construction du modèle de prédiction ‘’Machine learning‘’
Validation du modèle de prédiction
35
Chapitre 4 : Analyse des résultats
Dans ce qui suit, quelques figures d’analyse de désabonnement selon la distribution des
variables dans notre base de donnée.
La figure ci-dessous illustre la répartition de churn selon le genre des clients avec 49.8% des
femmes churn et 49.3% non churn et 50.2% des hommes churn et 50.7% non churn.
36
Chapitre 4 : Analyse des résultats
Ensuite, la variable utilisée c’est le service internet. Comme il est présenté dans la figure
suivante, 69.4% des clients churn utilise la service internet avec fibre optique, 24.6% ADSL
et 6.05% Ils n'ont pas de services internet. Pour les clients non churn 34.8% service fibre
optique, 37.9% ADSL et 27.3% n’utilise pas ce service. On remarque que le taux de
désabonnement de services internet avec fibre optique et élevée et c’est à cause de leurs couts.
37
Chapitre 4 : Analyse des résultats
38
Chapitre 4 : Analyse des résultats
Les deux histogrammes suivants présentent les variables numériques dans notre base de
données, la figure ci-dessous illustre le churn et le non churn selon le pourcentage de charge
mensuelle. De même pour la figure 29 qui présente la charge totale.
39
Chapitre 4 : Analyse des résultats
Dans les trois figures suivantes on utilise la dispersion groupée. C’est une pratique courante
dans le diagramme de dispersion qui permet d’étudier le comportement des groupes pour deux
variables choisies.
40
Chapitre 4 : Analyse des résultats
On a changé l’un des deux variables « Total Charges » par « Monthly charges ». On a trouvé
presque le même résultat, un taux de désabonnement élevé lors des premières périodes des
engagements et avec une augmentation en fonction d’augmentation de charges mensuelles.
41
Chapitre 4 : Analyse des résultats
La figure suivante illustre que le taux de désabonnement s’agrandir avec une charge totale et
une charge mensuelle élevée.
42
Chapitre 4 : Analyse des résultats
43
Chapitre 4 : Analyse des résultats
Nous affichons par ordre décroissant d’importance les variables dans la figure suivante. On
note surtout un fort décalage entre les trois premières variables et les autres variables.
D’après l’histogramme précédent nous pouvons détecter les paramètres les plus importants
pouvant influencer les désabonnements des clients « MonthlyCharges », « TotalCharges » et
« Tenure ».
44
Chapitre 4 : Analyse des résultats
La figure ci-dessus illustre l’importance des variables par ordre décroissante, Où il se divise
en deux catégories et nous donnes les variables importantes pour les deux, « TotalCharges »
pour les variables numériques et « contract_Month-to-Month » pour les variables
catégoriques.
45
Chapitre 4 : Analyse des résultats
166 198
952 91
AUC = 0.728
D’après ce modèle 1118 (Prédiction)/1043(réel) non churn et 289 (prédiction)/ 364 (réel)
churn avec un taux d’erreur 0.183.
La courbe ROC est un graphique représentant les performances, cette courbe trace le taux de
vrais positifs en fonction du taux de faux positifs. Plus la valeur de l'AUC est élevée, meilleur
est le modèle qui prédit, dans ce cas AUC=0.728.
46
Chapitre 4 : Analyse des résultats
67 297
774 269
AUC = 0.779
70 294
773 270
AUC = 0.774
47
Chapitre 4 : Analyse des résultats
L’affichage d’un arbre n’est pas aisé avec Python. Il faut travailler en deux temps : (1) créer
un fichier ‘.dot’ à partir de l’arbre généré. (2) que l’on fait traduire en image PNG avec le
logiciel GraphViz (qu’il faut installer au préalable) (cf. Russel, ‘’Creating and Visualizing
Decision Trees with Python’’, août 2017).
48
Chapitre 4 : Analyse des résultats
49
Chapitre 4 : Analyse des résultats
La racine a été segmentée avec la variable ‘’TotalesCarges’’, avec valeur seuil ‘’198.05’’. La
branche à gauche (True) correspond à la condition ‘’ TotalesCarges ≤ 198.05’’, la branche à
droite (False) à ‘’ TotalesCarges > 198.05’’. Etc. Chaque chemin aboutissant à une feuille
correspond à une règle. Pour comprendre le mécanisme d’affectation d’une classe à un
individu, il suffit de suivre la voie qu’il emprunte de la racine vers la feuille.
L'indice de Gini est une mesure permettant de mesurer la fréquence à laquelle un élément
choisi au hasard serait incorrectement identifié. Cela signifie qu'un attribut avec un indice de
gini inférieur devrait être préféré.
Sklearn prend en charge les critères « gini » pour Gini Index et prend par défaut la valeur «
gini ».
L'entropie est la mesure de l'incertitude d'une variable aléatoire, elle caractérise l'impureté
d'une collection arbitraire d'exemples. Plus l'entropie est élevée, plus le contenu de
l'information est important.
La figure suivante présente le courbe ROC et la matrice de confusion de décision tree qui
nous donnes 1043(réel)/ 861(prédiction) non churn et 364(réel)/546(prédiction) churn avec un
taux d’erreur = 0.222 et AUC = 0718.
50
Chapitre 4 : Analyse des résultats
105 259
756 287
AUC = 0.718
Les arbres de décision profonds peuvent souffrir de sur-ajustement, mais ils sont plus
rapides en calcul est facilement interprétable et peut être converti en règles.
Les forêts aléatoires sont un ensemble de plusieurs arbres de décision. Ils empêchent le sur-
ajustement en créant des arbres sur des sous-ensembles aléatoires, mais difficiles à interpréter,
Contrairement à un arbre de décision.
51
Chapitre 4 : Analyse des résultats
Figure 42 : RF ‘’Entropy‘’
52
Chapitre 4 : Analyse des résultats
263 101
1005 38
AUC = 0.620
99 391
934 334
AUC = 0.767
53
Chapitre 4 : Analyse des résultats
33 331
962 81
AUC = 0.915
26 338
1011 32
AUC = 0.948
54
Chapitre 4 : Analyse des résultats
23 341
1025 18
AUC = 0.959
Les trois derniers modèles nous donnent des meilleurs résultats pour la prédiction. Dans ce
qui suit on s’intéresse à la performance des modèles de prédiction.
Accuracy : Il s'agit simplement d'un ratio d'observations correctement prédites par rapport au
nombre total d'observations.
Accuracy = TP + TN / TP + FP + FN + TN
Précision : La précision est le rapport entre les observations positives correctement prédites et
le total des observations positives prédites
Précision = TP / TP + FP
Rappel : Le rappel est le rapport entre les observations positives correctement prédites et
toutes les observations de la classe réelle
Rappel = TP / TP + FN
55
Chapitre 4 : Analyse des résultats
56
Chapitre 4 : Analyse des résultats
57
Chapitre 4 : Analyse des résultats
4.7.2. Entraînement
Prenons l’exemple de l’arbre de décision, La séquence suivante défini une analyse de
prédiction par l’arbre de décision. Le composant Partitioning initie la boucle de prédiction à
partir des données d’apprentissage. Il est connecté à un outil d’apprentissage DECISION
TREE LEARNER, mais aussi à un outil prédictif DECISION TREE PREDICTOR.
Le nœud Equal size sampling pour supprimer les lignes aléatoires appartenant aux classes
majoritaires. Après cela, le modèle PMML est enregistré dans un fichier.
4.7.3. Évaluation
Pour l'évaluation, nous utilisons les 20% de données que nous avons gardées de côté et non
utilisées pendant la phase de formation pour alimenter un nœud de prédiction. Ce nœud
applique le modèle à toutes les lignes de données une par une et génère la probabilité que ce
client a créé des données en fonction de son contrat et de ses données opérationnelles (P
58
Chapitre 4 : Analyse des résultats
(Churn = YES/NO)). En fonction de la valeur de cette probabilité, une classe prédite sera
affectée à la ligne de données (Prédiction (Churn) = YES/NO).
Le nombre des fois où la classe prédite coïncide avec la classe de désabonnement d'origine
constitue la base de toute mesure de la qualité du modèle telle qu'elle est calculée par le nœud
Scorer.
4.7.4. Déploiement
Lorsque nous sommes satisfaits des performances de notre modèle, nous pouvons le faire
passer en production pour un déploiement sur des données réelles. Ici, il suffit de lire le flux
de données réelles provenant d’un fichier, d’une base de données et du modèle généré. Nous
appliquons ensuite un prédicteur PMML pour exécuter le modèle sur les données d'entrée
réelles. Les données de sortie contiendront quelques colonnes supplémentaires avec la classe
de prédiction.
59
Chapitre 4 : Analyse des résultats
Après l’explication des méthodes de validation, la figure suivante illustre tous la construction
de workflow de tous les modèles de notre recherche.
60
Chapitre 4 : Analyse des résultats
61
Chapitre 4 : Analyse des résultats
Maintenant on commence de traiter les résultats des modèles workflow et l’on compare avec
les résultats de modèles développé.
AUC=0.699
La figure suivante illustre les résultats de workflow décision tree avec un taux d’erreur
34.261% et AUC = 0.681, rappelons que le modèle développé donne des résultats plus au
moins meilleur un taux d’erreur 22.2% et AUC = 0.7.
62
Chapitre 4 : Analyse des résultats
AUC=0.681
Passant au résultat de RF un taux d’erreur 31.37% et AUC = 0.761 une comparaison avec le
modèle développé nous donnes AUC presque même valeur 0.724 mais d’un taux d’erreur plus
faible 17.9% donc une précision meilleure.la figure 56 illustre les résultats.
AUC=0.761
63
Chapitre 4 : Analyse des résultats
Les résultats de naïve bayes similaire à celle de modèle développé avec un taux d’erreur
24.732% et 24.7% de modèle développé, AUC = 0.793 et 0.775 de modèle développé. La
figure 57 illustre les résultats de modèle workflow.
AUC=0.793
Pour les résultats donnés par workflow SVM, un taux d’erreur trop élevé 46.146%
contrairement à celle de modèle développé 8.1%, mais avec AUC presque similaire 0.927
pour workflow et 0.916 pour le modèle développé.
64
Chapitre 4 : Analyse des résultats
AUC=0.927
Également pour les deux modèles LGBM et XGBoost, présentés par les figures suivantes, un
taux d’erreur trop élevé est observé. Ce qui montre que les modèles développés offrent des
meilleurs résultats que celle de workflow avec 4.1% respectivement 2.9% pour les taux
d’erreur et 0.949 respectivement 0.96 pour AUC.
AUC=0.898
65
Chapitre 4 : Analyse des résultats
AUC=0.825
66
Chapitre 4 : Analyse des résultats
La figure ci-dessus illustre une comparaison entre les résultats des modèles développés sous
python et celles des modèles workflows sous le logiciel d’analyse de données Knime. On a
une similitude au niveau de la courbe de AUC jusqu’à les trois derniers modèles. Les modèles
développés donnent des résultats meilleurs. En revanche, au niveau de taux d’erreur, les
modèles développés sous python offrent des résultats meilleurs ce qui montre la précision des
modèles développés.
4.8. Conclusion
Dans ce dernier chapitre, nous avons appliqué les différents concepts théoriques décrites
lors des chapitres précédents. Il s’agit d’une présentation des résultats de programmation, en
Python, des modèles de prédiction de taux de désabonnements des clients d’un opérateur de
télécommunication sous Jupyter-notebook, puis une construction workflow sous KNIME de
ces derniers afin de comparer et valider les résultats de notre code développé.
67
Conclusion Générale
La prévision du taux de désabonnement est l’une des sources de revenus les plus
importantes pour les entreprises de télécommunications. Par conséquent, cette recherche visait
à construire un système qui prédit le désabonnement des clients dans des sociétés de
télécommunications. Ces modèles de prédiction doivent atteindre des valeurs AUC
élevées. Pour tester et former le modèle, l'échantillon de données est divisé en 80% pour la
formation et 20% pour les tests. Nous avons appliqué l'ingénierie des caractéristiques, une
transformation efficace des caractéristiques et une approche de sélection afin de les préparer
pour les algorithmes d'apprentissage automatique. De plus, nous avons rencontré un autre
problème: les données n'étaient pas équilibrées. Environ 26.6% seulement des entrées
représentent le désabonnement des clients. Ce problème a été résolu en sous-échantillonnant
ou en utilisant des algorithmes d'arbres non affectés par ce problème. Trois algorithmes basés
sur la régression logistique, quatre algorithmes basés sur des arbres et deux autres algorithmes
un basé sur la classification linéaire et l’autre sur le théorème de bayes donc probabiliste ont
été choisis en raison de leur diversité et de leur applicabilité dans ce type de prédiction. Ces
algorithmes sont régression logistique, régression logistique SMOTE, régression logistique
RFE, Naïve Bayes et SVM respectivement l'arbre de décision, la forêt aléatoire, l'algorithme
d'arborescence GBM et l'algorithme XGBOOST. La méthode de préparation et de sélection
des fonctionnalités ainsi que la saisie des fonctionnalités ont eu le plus grand impact sur le
succès de ce modèle, puisque la valeur de l’AUC a atteint 96%. Le modèle arborescent
XGBOOST a obtenu les meilleurs résultats pour toutes les mesures. L'algorithme LGBM
vient en deuxième place et SVM viennent en troisième en ce qui concerne les valeurs de
l'AUC.
68
Webographie
[1]. http://www.marketing-professionnel.fr/tribune-libre/churn-marketing-predire-gerer-
attrition-perte-clients-201705.html, dernière visite le (23/04/2019).
[2]. https://www.zdnet.fr/actualites/big-data-quel-interet-pour-l-analyse-predictive-
39824666.htm, dernière visite le (29/04/2019).
[3]. https://www.futura-sciences.com/tech/definitions/big-data-data-mining-16876/,dernière
visite le (02/06/2019).
[4]. https://www.eurocloud.fr/machine-learning-linformatique-devient-de-plus-plus-
intelligente/, dernière visite le (02/06/2019).
[5]. https://moov.ai/fr/blog/predire-le-desabonnement-de-clients-grace-a-lapprentissage-
machine/, dernière visite le (17/06/2019).
[6]. https://www.memoireonline.com/08/13/7308/m_Analyse-et-detection-de-lattrition-dans-
une-entreprise-de-telecommunication21.html, dernière visite le (13/08/2019).
[7]. https://www.lebigdata.fr/data-mining-definition-exemples, dernière visite le (29/08/2019).
[8]. https://www.fromthegenesis.com/pros-and-cons-of-k-nearest-neighbors/, dernière visite le
(07/09/2019).
[9]. https://www.geeksforgeeks.org/ml-handling-imbalanced-data-with-smote-and-near-miss-
algorithm-in-python/, dernière visite le (10/09/2019).
[10]. https://www.analyticsvidhya.com/blog/2017/06/which-algorithm-takes-the-crown-light-
gbm-vs-xgboost/, dernière visite le (23/09/2019).
[11]. https://www.python-course.eu/Decision_Trees.php, dernière visite le (01/10/2019).
[12]. https://www.analyticsvidhya.com/blog/2017/06/which-algorithm-takes-the-crown-light-
gbm-vs-xgboost/, dernière visite le (03/10/2019).
[13]. https://fr.wikipedia.org/wiki/Pr%C3%A9cision_et_rappel, dernière visite le
(18/10/2019).
69
Bibliographie
[B1]. MÉMOIRE DE MASTER RECHERCHE [Implémentation et test d'une solution de la
prédiction en utilisant les technologies du Big Data et Machine Learning]
[B2]. Wei CP, Chiu IT. Transformer les détails des appels de télécommunication en
prévisions de désabonnement: une approche d'exploration de données. Expert Syst
Appl. 2002; 23 (2): 103-12.Voir l'articleGoogle Scholar
[B3]. Qureshii SA, AS Rehman, AM Qamar, Kamal A, Rehman A. Modèle de prévision du
taux de désabonnement des abonnés des services de télécommunication utilisant
l'apprentissage automatique. In: Huitième conférence internationale sur la gestion de
l'information numérique. 2013. p. 131–6.Google Scholar
[B4]. SVM-Support Vector Machine/ Machines à Vecteurs de Support–Séparateurs à Vaste
Marge [Ricco Rakotomalala Université Lumière Lyon 2] .Voir l'articleGoogle Scholar
70
Annexes
Code source du projet de prédiction
N.B. merci de lancer le code par bloc pour une meilleure visibilité du résultat et une nette
qualité du rendu, les blocs sont séparer par une série des dièses.
##########Manipulation de donnée
#Remplacer des espaces avec des valeurs NULL dans la colonne des charges totales
telcom['TotalCharges'] = telcom["TotalCharges"].replace(" ",np.nan)
# Suppression des valeurs nulles de la colonne des charges totales
telcom = telcom[telcom["TotalCharges"].notnull()]
telcom = telcom.reset_index()[telcom.columns]
#convert to float type
telcom["TotalCharges"] = telcom["TotalCharges"].astype(float)
# remplace 'No internet service' par 'No' pour les colonnes suivantes
replace_cols = [ 'OnlineSecurity', 'OnlineBackup', 'DeviceProtection',
'TechSupport','StreamingTV', 'StreamingMovies']
for i in replace_cols :
telcom[i] = telcom[i].replace({'No internet service' : 'No'})
71
# remplacer les valeurs
telcom["SeniorCitizen"] = telcom["SeniorCitizen"].replace({1:"Yes",0:"No"})
# Durée de service dans la colonne catégorique
def tenure_lab(telcom) :
if telcom["tenure"] <= 12 :
return "Tenure_0-12M"
elif (telcom["tenure"] > 12) & (telcom["tenure"] <= 24 ):
return "Tenure_12-24M"
elif (telcom["tenure"] > 24) & (telcom["tenure"] <= 48) :
return "Tenure_24-48M"
elif (telcom["tenure"] > 48) & (telcom["tenure"] <= 60) :
return "Tenure_48-60M"
elif telcom["tenure"] > 60 :
return "Tenure_+60M"
telcom["tenure_group"] = telcom.apply(lambda telcom:tenure_lab(telcom),
axis = 1)
# Separer churn and non churn customers
churn = telcom[telcom["Churn"] == "Yes"]
not_churn = telcom[telcom["Churn"] == "No"]
# Séparer les colonnes catégoriques et numériques
Id_col = ['customerID']
target_col = ["Churn"]
cat_cols = telcom.nunique()[telcom.nunique() < 6].keys().tolist()
cat_cols = [x for x in cat_cols if x not in target_col]
num_cols = [x for x in telcom.columns if x not in cat_cols + target_col + Id_col]
data = [trace]
fig = go.Figure(data = data,layout = layout)
py.iplot(fig)
72
#function pie plot pour classification des clients(churn¬churn) selon les colonnes
catégoriques
def plot_pie(column) :
trace1 = go.Pie(values = churn[column].value_counts().values.tolist(),
labels = churn[column].value_counts().keys().tolist(),
hoverinfo = "label+percent+name",
domain = dict(x = [0,.48]),
name = "Churn_Customers",
marker = dict(line = dict(width = 2,
color = "rgb(243,243,243)")
)
)
trace2 = go.Pie(values = not_churn[column].value_counts().values.tolist(),
labels = not_churn[column].value_counts().keys().tolist(),
hoverinfo = "label+percent+name",
marker = dict(line = dict(width = 2,
color = "rgb(243,243,243)")
),
domain = dict(x = [.52,1]),
name = "Non_churn_customers"
)
layout = go.Layout(dict(title = "column_"+ column,
plot_bgcolor = "rgb(243,243,243)",
paper_bgcolor = "rgb(243,243,243)",
annotations = [dict(text = "churn",
font = dict(size = 10),
showarrow = False,
x = .25, y = .5),
dict(text = "Non_churn",
font = dict(size = 10),
showarrow = False,
x = .8,y = .5
)
]
)
)
data = [trace1,trace2]
fig = go.Figure(data = data,layout = layout)
py.iplot(fig)
#for all plot pie
for i in cat_cols :
plot_pie(i)
##########Colones numériques
#function histogram pour classification des clients(churn¬churn) selon le
mondat&Frais_mensuels&Charges_totales
def histogram(column) :
trace1 = go.Histogram(x = churn[column],
histnorm= "percent",
name = "Churn",
73
marker = dict(line = dict(width = .75,
color = "black"
)
),
opacity = .9
)
trace2 = go.Histogram(x = not_churn[column],
histnorm = "percent",
name = "Non_churn",
marker = dict(line = dict(width = .75,
color = "black"
)
),
opacity = .9
)
data = [trace1,trace2]
layout = go.Layout(dict(title ="Répartition_des_clients_" + column,
plot_bgcolor = "rgb(243,243,243)",
paper_bgcolor = "rgb(243,243,243)",
xaxis = dict(gridcolor = 'rgb(255, 255, 255)',
title = column,
zerolinewidth=1,
ticklen=5,
gridwidth=2
),
yaxis = dict(gridcolor = 'rgb(255, 255, 255)',
title = "percent",
zerolinewidth=1,
ticklen=5,
gridwidth=2
),
)
)
fig = go.Figure(data=data,layout=layout)
py.iplot(fig)
#for all plot histogram
for i in num_cols :
histogram(i)
74
trace2 = go.Bar(x = tg_nch["tenure_group"] , y = tg_nch["count"],
name = "Non_Churn",
marker = dict(line = dict(width = .5,color = "black")),
opacity = .9)
layout = go.Layout(dict(title = "Répartition_des_clients_selon_periode_d'abonnement",
plot_bgcolor = "rgb(243,243,243)",
paper_bgcolor = "rgb(243,243,243)",
xaxis = dict(gridcolor = 'rgb(255, 255, 255)',
title = "tenure group",
zerolinewidth=1,ticklen=5,gridwidth=2),
yaxis = dict(gridcolor = 'rgb(255, 255, 255)',
title = "count",
zerolinewidth=1,ticklen=5,gridwidth=2),
)
)
data = [trace1,trace2]
fig = go.Figure(data=data,layout=layout)
py.iplot(fig)
75
layout2 = layout_title("")
fig2 = go.Figure(data = data2,layout = layout2)
py.iplot(fig2)
76
)
return tracer
trace6 = plot_churncharges_scatter("Yes","#030303")
trace7 = plot_churncharges_scatter("No","#FAF80D")
data2 = [trace7,trace6]
#layout
def layout_title(title) :
layout = go.Layout(dict(title = title,
plot_bgcolor = "rgb(243,243,243)",
paper_bgcolor = "rgb(243,243,243)",
xaxis = dict(gridcolor = 'rgb(255, 255, 255)',
title = "tenure",
zerolinewidth=1,ticklen=5,gridwidth=2),
yaxis = dict(gridcolor = 'rgb(255, 255, 255)',
title = "MonthlyCharges",
zerolinewidth=1,ticklen=5,gridwidth=2),
height = 600
)
)
return layout
layout2 = layout_title("")
fig2 = go.Figure(data = data2,layout = layout2)
py.iplot(fig2)
77
#dropping original values merging scaled values for numerical columns
df_telcom_og = telcom.copy()
telcom = telcom.drop(columns = num_cols,axis = 1)
telcom = telcom.merge(scaled,left_index=True,right_index=True,how = "left")
##########corrélation
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize = (25,15))
sns.heatmap(telcom.corr(method='pearson'), annot=True, fmt='.1f',
cmap=plt.get_cmap('YlGnBu'), cbar=False, ax=ax)
ax.set_yticklabels(ax.get_yticklabels())
plt.savefig('result.jpeg')
##########regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix,accuracy_score,classification_report
from sklearn.metrics import roc_auc_score,roc_curve,scorer
from sklearn.metrics import f1_score
import statsmodels.api as sm
from sklearn.metrics import precision_score,recall_score
from yellowbrick.classifier import DiscriminationThreshold
#fractionnement des données de train et de test
train,test = train_test_split(telcom,test_size = .2 ,random_state = 1000)
#séparer les variables dépendantes et indépendantes
cols = [i for i in telcom.columns if i not in Id_col + target_col]
train_X = train[cols]
train_Y = train[target_col]
test_X = test[cols]
test_Y = test[target_col]
# Attributs de fonction
# dataframe - trame de données traitée
# Algorithm - Algorithme utilisé
# training_x - trame de données de variables prédictives (formation)
# testing_x - variables du prédicteur dataframe (testing)
# training_y - variable cible (training)
# training_y - variable cible (test)
# cf - ["coefficients", "features"] (cooefficients pour la logistique
# régression, fonctionnalités pour les modèles arborescents)
# threshold_plot - si True renvoie le tracé du seuil pour le modèle
def telecom_churn_prediction(algorithm,training_x,testing_x,
training_y,testing_y,cols,cf,threshold_plot) :
#model
algorithm.fit(training_x,training_y)
predictions = algorithm.predict(testing_x)
probabilities = algorithm.predict_proba(testing_x)
78
#coeffs
if cf == "coefficients" :
coefficients = pd.DataFrame(algorithm.coef_.ravel())
elif cf == "features" :
coefficients = pd.DataFrame(algorithm.feature_importances_)
column_df = pd.DataFrame(cols)
coef_sumry = (pd.merge(coefficients,column_df,left_index= True,
right_index= True, how = "left"))
coef_sumry.columns = ["coefficients","features"]
coef_sumry = coef_sumry.sort_values(by = "coefficients",ascending = False)
print (algorithm)
print ("\n Classification report : \n",classification_report(testing_y,predictions))
print ("Accuracy Score : ",accuracy_score(testing_y,predictions))
#confusion matrix
conf_matrix = confusion_matrix(testing_y,predictions)
#roc_auc_score
model_roc_auc = roc_auc_score(testing_y,predictions)
print ("Area under curve : ",model_roc_auc,"\n")
fpr,tpr,thresholds = roc_curve(testing_y,probabilities[:,1])
#plot confusion matrix
trace1 = go.Heatmap(z=conf_matrix,
x = ["Not churn","Churn"],
y = ["Not churn","Churn"],
showscale = True ,colorscale = "Portland",
name = "matrix",xaxis="x2",yaxis="y2")
#plot roc curve
trace2 = go.Scatter(x = fpr,y = tpr,
name = "Roc : " + str(model_roc_auc),
line = dict(color = ('#000103'),width = 2),
)
trace3 = go.Scatter(x = [0,1],y=[0,1],
line = dict(color = ('#fc0505'),width = 2,
dash = 'dot'))
#plot coeffs
trace4 = go.Bar(x = coef_sumry["features"],y = coef_sumry["coefficients"],
name = "coefficients"
,
marker = dict(color = coef_sumry["coefficients"],
colorscale = "blues",
line = dict(width = .6,color = "black")))
layout = go.Layout(dict(title="Performance_du_modèle
Matrice_de_confusion",
autosize = False,height = 500,width = 800,
showlegend = False,
plot_bgcolor = "rgb(243,243,243)",
paper_bgcolor = "rgb(243,243,243)",
xaxis = dict(title= 'Courbe_ROC(Receiver operating characteristic)',
gridcolor = 'rgb(255, 255, 255)',
domain=[0, 0.6],ticklen=5,gridwidth=2),
79
yaxis = dict(gridcolor = 'rgb(255, 255, 255)',
zerolinewidth=1,
ticklen=5,gridwidth=2),
margin = dict(b=200),
xaxis2 =dict(title ="Positive/Negative(actual)",
domain =[0.7, 1],
gridcolor = 'rgb(255, 255, 255)') ,
yaxis2 =dict(title = "Positive/Negative(prédiction)",
anchor='x2',gridcolor = 'rgb(255, 255, 255)')
)
)
data = [trace1,trace2,trace3]
fig = go.Figure(data=data,layout=layout)
py.iplot(fig)
layout = go.Layout(dict(title = "Feature_Importances",
autosize = False,height = 800,width = 800,
plot_bgcolor = "rgb(243,243,243)",
paper_bgcolor = "rgb(243,243,243)",
)
)
data1=[trace4]
fig1=go.Figure(data1,layout=layout)
py.iplot(fig1)
logit = LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
verbose=0, warm_start=False)
telecom_churn_prediction(logit,train_X,test_X,train_Y,test_Y,
cols,"coefficients",threshold_plot = True)
##########
from imblearn.over_sampling import SMOTE
cols = [i for i in telcom.columns if i not in Id_col+target_col]
smote_X = telcom[cols]
smote_Y = telcom[target_col]
#Données de train et d'essai fractionnées
smote_train_X,smote_test_X,smote_train_Y,smote_test_Y =
train_test_split(smote_X,smote_Y,
test_size = .1 ,
random_state = 100)
80
verbose=0, warm_start=False)
telecom_churn_prediction(logit_smote,os_smote_X,test_X,os_smote_Y,test_Y,
cols,"coefficients",threshold_plot = True)
##########
from sklearn.feature_selection import RFE
logit = LogisticRegression()
rfe = RFE(logit,10)
rfe = rfe.fit(os_smote_X,os_smote_Y.values.ravel())
rfe.support_
rfe.ranking_
#colonnes identifiées Élimination récursive de caractéristiques
idc_rfe = pd.DataFrame({"rfe_support" :rfe.support_,
"columns" : [i for i in telcom.columns if i not in Id_col + target_col],
"ranking" : rfe.ranking_,
})
cols = idc_rfe[idc_rfe["rfe_support"] == True]["columns"].tolist()
#separating train and test data
train_rf_X = os_smote_X[cols]
train_rf_Y = os_smote_Y
test_rf_X = test[cols]
test_rf_Y = test[target_col]
logit_rfe = LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
verbose=0, warm_start=False)
#applying model
telecom_churn_prediction(logit_rfe,train_rf_X,test_rf_X,train_rf_Y,test_rf_Y,
cols,"coefficients",threshold_plot = True)
tab_rk = ff.create_table(idc_rfe)
py.iplot(tab_rk)
##########
from sklearn.feature_selection import chi2
from sklearn.feature_selection import SelectKBest
#select columns
cols = [i for i in telcom.columns if i not in Id_col + target_col ]
#dataframe with non negative values
df_x = df_telcom_og[cols]
df_y = df_telcom_og[target_col]
#fit model with k= 3
select = SelectKBest(score_func = chi2,k = 3)
fit = select.fit(df_x,df_y)
#Summerize scores
print ("scores")
print (fit.scores_)
print ("P - Values")
print (fit.pvalues_)
#create dataframe
81
score = pd.DataFrame({"features":cols,"scores":fit.scores_,"p_values":fit.pvalues_ })
score = score.sort_values(by = "scores" ,ascending =False)
#createing new label for categorical and numerical columns
score["feature_type"] =
np.where(score["features"].isin(num_cols),"Numerical","Categorical")
#plot
trace = go.Scatter(x = score[score["feature_type"] == "Categorical"]["features"],
y = score[score["feature_type"] == "Categorical"]["scores"],
name = "Categorial",mode = "lines+markers",
marker = dict(color = "green",
line = dict(width =1))
)
trace1 = go.Bar(x = score[score["feature_type"] == "Numerical"]["features"],
y = score[score["feature_type"] == "Numerical"]["scores"],name = "Numerical",
marker = dict(color = "red",
line = dict(width =1)),
xaxis = "x2",yaxis = "y2"
)
layout = go.Layout(dict(title = "Scores_Categorical & Numerical_features",
plot_bgcolor = "rgb(243,243,243)",
paper_bgcolor = "rgb(243,243,243)",
xaxis = dict(gridcolor = 'rgb(255, 255, 255)',
tickfont = dict(size =10),
domain=[0, 0.7],
tickangle = 90,zerolinewidth=1,
ticklen=5,gridwidth=2),
yaxis = dict(gridcolor = 'rgb(255, 255, 255)',
title = "scores",
zerolinewidth=1,ticklen=5,gridwidth=2),
margin = dict(b=200),
xaxis2=dict(domain=[0.8, 1],tickangle = 90,
gridcolor = 'rgb(255, 255, 255)'),
yaxis2=dict(anchor='x2',gridcolor = 'rgb(255, 255, 255)')
)
)
data=[trace,trace1]
fig = go.Figure(data=data,layout=layout)
py.iplot(fig)
##########
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
from sklearn import tree
from graphviz import Source
from IPython.display import SVG,display
import ipywidgets as wg
from ipywidgets import interactive
#top 3 categorical features
features_cat = score[score["feature_type"] == "Categorical"]["features"][:1].tolist()
#top 3 numerical features
82
features_num = score[score["feature_type"] == "Numerical"]["features"][:1].tolist()
# Attributs de fonction
# colonnes - colonnes sélectionnées
# maximum_depth - profondeur de l'arbre
# critere_type - ["gini" ou "entropie"]
# split_type - ["meilleur" ou "aléatoire"]
# Model Performance - True (donne la sortie du modèle
def plot_decision_tree(columns,maximum_depth,criterion_type,
split_type,model_performance = None) :
#séparer les variables dépendantes et indépendantes
dtc_x = df_x[columns]
dtc_y = df_y[target_col]
#model
dt_classifier = DecisionTreeClassifier(max_depth = maximum_depth,
splitter = split_type,
criterion = criterion_type,
)
dt_classifier.fit(dtc_x,dtc_y)
#plot decision tree
graph = Source(tree.export_graphviz(dt_classifier,out_file=None,
rounded=False,
proportion = False,
feature_names = columns,
precision = 2,
class_names=["Not churn","Churn"],
filled = True
)
)
display(graph)
plot_decision_tree(features_num,3,"gini","best")
##########
from sklearn.ensemble import RandomForestClassifier
# attributs de fonction
# colonnes - colonne utilisée
# nf_estimators - Le nombre d'arbres dans la forêt.
# installed_tree - numéro d'arbre à afficher
# maximum_depth - profondeur de l'arbre
# critere_type - type de critere scinde ["gini" ou "entropie"]
# Performance du modèle - imprime les performances du modèle
def plot_tree_randomforest(columns,nf_estimators,
estimated_tree,maximum_depth,
criterion_type,model_performance = None) :
dataframe = df_telcom_og[columns + target_col].copy()
#train and test datasets
rf_x = dataframe[[i for i in columns if i not in target_col]]
rf_y = dataframe[target_col]
83
rfc = RandomForestClassifier(n_estimators = nf_estimators,
max_depth = maximum_depth,
criterion = criterion_type,
)
rfc.fit(rf_x,rf_y)
estimated_tree = rfc.estimators_[estimated_tree]
graph = Source(tree.export_graphviz(estimated_tree,out_file=None,
rounded=False,proportion = False,
feature_names = columns,
precision = 2,
class_names=["Not churn","Churn"],
filled = True))
display(graph)
#model performance
if model_performance == True :
telecom_churn_prediction(rfc,
rf_x,test_X[columns],
rf_y,test_Y,
columns,"features",threshold_plot = True)
##########
from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB(priors=None)
telecom_churn_prediction_alg(gnb,os_smote_X,test_X,os_smote_Y,test_Y)
##########
from sklearn.svm import SVC
#Support vector classifier
#using linear hyper plane
svc_lin = SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma=1.0, kernel='linear',
max_iter=-1, probability=True, random_state=None, shrinking=True,
tol=0.001, verbose=False)
cols = [i for i in telcom.columns if i not in Id_col + target_col]
telecom_churn_prediction(svc_lin,os_smote_X,test_X,os_smote_Y,test_Y,
cols,"coefficients",threshold_plot = False)
##########
from lightgbm import LGBMClassifier
84
cols = [i for i in telcom.columns if i not in Id_col + target_col]
telecom_churn_prediction(lgbm_c,os_smote_X,test_X,os_smote_Y,test_Y,
cols,"features",threshold_plot = True)
##########
from xgboost import XGBClassifier
telecom_churn_prediction(xgc,os_smote_X,test_X,os_smote_Y,test_Y,
cols,"features",threshold_plot = True)
##########
from sklearn.metrics import f1_score
from sklearn.metrics import cohen_kappa_score
#gives model report in dataframe
def model_report(model,training_x,testing_x,training_y,testing_y,name) :
model.fit(training_x,training_y)
predictions = model.predict(testing_x)
accuracy = accuracy_score(testing_y,predictions)
recallscore = recall_score(testing_y,predictions)
precision = precision_score(testing_y,predictions)
roc_auc = roc_auc_score(testing_y,predictions)
f1score = f1_score(testing_y,predictions)
df = pd.DataFrame({"Model" : [name],
"Accuracy(%)" : [accuracy*100],
"Recall(%)" : [recallscore*100],
"Precision(%)" : [precision*100],
"f1_score(%)" : [f1score*100],
"AUC" : [roc_auc],
"error_rate(%)" : [(1-accuracy)*100],
})
return df
#outputs for every model
model1 = model_report(logit,train_X,test_X,train_Y,test_Y,
"LR")
model2 = model_report(logit_smote,os_smote_X,test_X,os_smote_Y,test_Y,
"LR(SMOTE)")
model3 = model_report(logit_rfe,train_rf_X,test_rf_X,train_rf_Y,test_rf_Y,
"LR(RFE)")
decision_tree = DecisionTreeClassifier(max_depth = 9,
random_state = 123,
splitter = "best",
criterion = "gini",
85
)
model4 = model_report(decision_tree,train_X,test_X,train_Y,test_Y,
"Decision Tree")
rfc = RandomForestClassifier(n_estimators = 1000,
random_state = 123,
max_depth = 9,
criterion = "gini")
model6 = model_report(rfc,train_X,test_X,train_Y,test_Y,
"Random Forest")
model7 = model_report(gnb,os_smote_X,test_X,os_smote_Y,test_Y,
"Naive Bayes")
model8 = model_report(svc_rbf,os_smote_X,test_X,os_smote_Y,test_Y,
"SVM")
model9 = model_report(lgbm_c,os_smote_X,test_X,os_smote_Y,test_Y,
"LGBM")
model10 = model_report(xgc,os_smote_X,test_X,os_smote_Y,test_Y,
"XGBoost")
#concat all models
model_performances = pd.concat([model1,model2,model3,
model4,model6,
model7,model8,model9,
model10],axis = 0).reset_index()
model_performances = model_performances.drop(columns = "index",axis =1)
colorscale = [[0, '#4d004c'],[.5, '#f2e5ff'],[1, '#ffffff']]
table = ff.create_table(np.round(model_performances,3),colorscale=colorscale)
py.iplot(table)
##########
model_performances
def output_tracer(metric,color) :
tracer = go.Scatter(x = model_performances["Model"] ,
y = model_performances[metric],
name = metric ,
marker = dict(line = dict(width =.7))
)
return tracer
layout = go.Layout(dict(plot_bgcolor = "rgb(243,243,243)",
paper_bgcolor = "rgb(243,243,243)",
xaxis = dict(gridcolor = 'rgb(255, 255, 255)',
title = "metric",
zerolinewidth=1,
ticklen=5,gridwidth=2),
yaxis = dict(gridcolor = 'rgb(255, 255, 255)',
zerolinewidth=1,ticklen=5,gridwidth=2),
margin = dict(l = 50),
height = 780
)
)
trace1 = output_tracer("Accuracy(%)","#6699FF")
trace2 = output_tracer('Recall(%)',"red")
trace3 = output_tracer('Precision(%)',"#33CC99")
86
trace4 = output_tracer('f1_score(%)',"lightgrey")
trace5 = output_tracer('AUC(%)',"yellow")
trace6 = output_tracer('error_rate(%)',"#000000")
data = [trace1,trace2,trace3,trace4,trace5,trace6]
fig = go.Figure(data=data,layout=layout)
py.iplot(fig)
87
Résumé
La perte de clientèle est un problème majeur et l’une des préoccupations majeures des grandes
entreprises. En raison de l’effet direct sur les revenus des entreprises, en particulier dans le
secteur des télécommunications, les entreprises cherchent à mettre au point des moyens de
prédire le nombre de clients potentiels à la fermeture. Par conséquent, il est important de
rechercher les facteurs qui augmentent le taux de désabonnement des clients pour prendre les
mesures adéquates. La principale contribution de notre travail est de développer un modèle de
prévision du taux de désabonnement qui aide les opérateurs de télécommunications à prédire
les clients les plus susceptibles de subir un désabonnement. Le modèle développé dans ce
travail utilise des techniques d'apprentissage automatique, sur jupyter-notebook, afin de
développer un modèle pour mesurer leur performance, la mesure standard de l'aire sous la
courbe (AUC) et le Matrice de confusion.
Abstract
Customer churn is a major problem and one of the most important concerns for large
companies. Due to the direct effect on the revenues of the companies, especially in the
telecom field, companies are seeking to develop a model to predict potential customer to
churn. Therefore, finding factors that increase customer churn is important to take necessary
actions to reduce this churn. The main contribution of our work is to develop a churn
prediction model which assists telecom operators to predict customers who are most likely
subject to churn. The model developed in this work uses machine learning techniques, on
jupyter-notebook, in order to developed and measure the performance of the model, using the
Area Under Curve (AUC) and the Confusion Matrix.
5 rue Salah Ayache 7100 Le Kef Tunisie 5 الكاف عياش صالح شارع7100 تونس
Tél. : 21678 201 الهاتف: 056 Fax : 21678 200 الفاكس: 237
Site web:www.isikef.rnu.tn: اإللكتون الموقع