Predict the income for each percentile of the population (Python) - FRENCH

Overview

05.income-prediction

Predict the income for each percentile of the population (Python) - FRENCH

Effectuez une prédiction de revenus

Prérequis

Pour ce projet, il sera utile de savoir réaliser une analyse de statistique descriptive en langages R ou Python (avec des représentations graphiques). Il faudra également appliquer des modélisations de type ANOVA ou régression linéaire.

Scénario

Vous êtes employé dans une banque, présente dans de nombreux pays à travers le monde. Celle-ci souhaite cibler de nouveaux clients potentiels, plus particulièrement les jeunes en âge d'ouvrir leur tout premier compte bancaire.

Cependant, elle souhaite cibler les prospects les plus susceptibles d'avoir, plus tard dans leur vie, de hauts revenus.

L'équipe dans laquelle vous travaillez a donc reçu pour mission de créer un modèle permettant de déterminer le revenu potentiel d'une personne.

Très bien.

"Quelles informations avons-nous ?" demandez-vous à votre supérieur, qui vous répond : "À vrai dire... quasiment aucune : uniquement le revenu des parents, car nous allons cibler les enfants de nos clients actuels, ainsi que le pays où ils habitent. C'est tout ! Ah oui, une dernière chose : ce modèle doit être valable pour la plupart des pays du monde. Je vous laisse méditer là-dessus… Bon courage !"

Avec aussi peu de données disponibles, cela semble être un sacré challenge !

Ainsi, vous proposez une régression linéaire avec 3 variables :

le revenu des parents ; le revenu moyen du pays dans lequel habite le prospect ; l'indice de Gini calculé sur les revenus des habitants du pays en question. Ce projet ne traite que de la construction et de l'interprétation du modèle. Vous n'irez pas jusqu'à la phase de prédiction

Les données Ce fichier contient les données de la World Income Distribution, datée de 2008.

Cette base de données est composée principalement d'études réalisées au niveau national pour bon nombre de pays, et contient les distributions de revenus des populations concernées.

Vous téléchargerez également les indices de Gini estimés par la Banque mondiale, disponibles à cette adresse. Libre à vous de trouver également d'autres sources, ou de recalculer les indices de Gini à partir de la World Income Distribution.

Vous aurez également besoin de récupérer le nombre d'habitants de chaque pays présent dans votre base.

Vos missions Mission 1 Résumez les données utilisées :

année(s) des données utilisées ; nombre de pays présents ; population couverte par l'analyse (en termes de pourcentage de la population mondiale). Les données de la World Income Distribution présentent pour chaque pays les quantiles de la distribution des revenus de leur population respective.

De quel type de quantiles s'agit-il (quartiles, déciles, etc.) ? Échantillonner une population en utilisant des quantiles est-il selon vous une bonne méthode ? Pourquoi ? Nous appellerons ici chaque quantile une classe de revenu. Ainsi, la valeur de la colonne income pour un quantile donné peut être vue comme le revenu moyen des personnes appartenant à la classe de revenu correspondante à ce quantile.

L'unité utilisée dans la colonne income de la world income distribution est le $PPP. Cette unité est calculée par la Banque mondiale, selon la méthode Eltöte-Köves-Szulc. Après vous être documenté, vous expliquerez à votre mentor très brièvement à quoi correspond cette unité et pourquoi elle est pertinente pour une comparaison de pays différents (Il n'est pas nécessaire de donner cette explication lors de la soutenance).

Mission 2 Montrez la diversité des pays en termes de distribution de revenus à l'aide d'un graphique. Celui-ci représentera le revenu moyen (axe des ordonnées, sur une échelle logarithmique) de chacune des classes de revenus (axe des abscisses) pour 5 à 10 pays que vous aurez choisis pour montrer la diversité des cas. Représentez la courbe de Lorenz de chacun des pays choisis. Pour chacun de ces pays, représentez l'évolution de l'indice de Gini au fil des ans. Classez les pays par indice de Gini. Donnez la moyenne, les 5 pays ayant l'indice de Gini le plus élevé et les 5 pays ayant l'indice de Gini le plus faible. En quelle position se trouve la France ?

Mission 3 Dans l'état actuel, nous avons à disposition deux des trois variables explicatives souhaitées :

(m_{j}) le revenu moyen du pays (j)

(G_{j}) l'indice de Gini du pays (j)

Il nous manque donc, pour un individu (i) , la classe de revenu (c_{i,parent}) de ses parents.

Nous supposons ici que l'on associe à chaque individu (i) une unique classe (c_{i,parent}) ; quel que soit le nombre de parents de (i).

Nous allons donc simuler cette information grâce à un coefficient (\rho_{j}) (propre à chaque pays (j) ), mesurant une corrélation entre le revenu de l'individu (i) et le revenu de ses parents. Ce coefficient sera ici appelé coefficient d'élasticité ; il mesure la mobilité intergénérationnelle du revenu.

Pour plus d'informations sur le calcul du coefficient d'élasticité, consulter ce document, notamment l'équation 1 de la page 8. Ce coefficient est déterminé par une régression linéaire simple dans laquelle le logarithme du revenu de l'enfant (Y_{child}) est une fonction du logarithme du revenu des parents (Y_{parent}) :

[ln(Y_{child}) = \alpha + \rho_j\ ln(Y_{parent}) + \epsilon]

Pour obtenir le coefficient d'élasticité, deux possibilités s'offrent à vous :

Vous baser sur ces coefficients donnés par la Banque mondiale, dans GDIM dataset. Le coefficient d'élasticité est donné pour certains pays, sous le nom d'IGE Income (relative IGM in income). Vous baser sur des estimations provenant de multiples études, extrapolées à différentes régions du monde : elles se trouvent dans le fichier elasticity.txt. Attention, ces données sont parfois anciennes. Il est aussi possible de combiner ces deux approches.

Pour chaque pays, nous allons utiliser une génération aléatoire de la classe de revenu des parents, à partir de ces seules deux informations :

(\rho_j) la classe de revenu de l'enfant (c_{i,child}). Attention à bien utiliser la classe de revenu de l'enfant (qui est un nombre compris entre 1 et 100 si vous utilisez 100 quantiles), plutôt que son revenu PPP. De même, on ne cherche pas à générer le revenu des parents, mais la classe de revenu des parents (c_{i,parent}).

Voici le protocole de génération pour un pays (j) donné, qui se base sur l'équation donnée ci dessus :

Un exemple de code permettant de réaliser les opérations 1 à 6 est donné tout en bas. Libre à vous de l'utiliser. Notamment, la fonction proba_cond vous donnera les probabilités (P(c_{i,parent}|c_{i,child},j)).

Générez un grand nombre (n) de réalisations d'une variable que nous appellerons (ln(Y_{parent})) selon une loi normale. Le choix de la moyenne et de l'écart type n'auront pas d'incidence sur le résultat final. (n) doit être supérieur à 1000 fois le nombre de quantiles. Générez (n) réalisations du terme d'erreur (\epsilon) selon une loi normale de moyenne 0 et d'écart type 1. Pour une valeur donnée de (\rho_j) (par exemple 0.9), calculez (y_{child} = e^{\alpha+\rho_jln(y_{parent})+\epsilon}) . Le choix de ( \alpha) n'a aucune incidence sur le résultat final et peut être supprimé. À ce stade, (y_{child}) contient des valeurs dont l'ordre de grandeur ne reflète pas la réalité, mais cela n'a pas d'influence pour la suite. Pour chacun des (n) individus générés, calculez la classe de revenu (c_{i,child}) ainsi que la classe de revenu de ses parents (c_{i,parent}) , à partir de (y_{child}) et (y_{parent}). À partir de cette dernière information, estimez pour chaque (c_{i,child}) la distribution conditionnelle de (c_{i,parent}) . Par exemple, si vous observez 6 individus ayant à la fois (c_{i,child} = 5) et (c_{i,parent} = 8) , et que 200 individus sur 20000 ont ( c_{i,child} = 5) , alors la probabilité d'avoir ( c_{i,parent} = 8) sachant (c_{i,child} = 5) et sachant (\rho_j=0.9) sera estimée à 6/200 (On note cette probabilité comme ceci : (P(c_{i,parent}=8|c_{i,child}=5,\rho_j=0.9) = 0.03)). Si votre population est divisée en (c) classes de revenu, vous devriez alors avoir (c^2) estimations de ces probabilités conditionnelles, pour chaque pays. Optionnellement et pour vérifier la cohérence de votre code, vous pouvez créer un graphique représentant ces distributions conditionnelles. Voici 2 exemples pour une population segmentée en 10 classes, pour 2 valeurs de (\rho_j) : l'une traduisant une forte mobilité (0.1) et l'autre une très faible mobilité (0.9) : Faible mobilité Forte mobilité Forte mobilité Faible mobilité Éventuellement et pour éviter toute confusion, effacez les individus que vous venez de générer (nous n'en avons plus besoin), et ne gardez que les distributions conditionnelles. Nous allons maintenant travailler sur un nouvel échantillon. Celui-ci sera créé à partir de la WID. Pour chaque individu de la World Income Distribution, créez-en 499 "clones". La taille de votre nouvel échantillon sera donc 500 fois plus grand que celui de la World Income Distribution. Pour chaque (c_{i,child}) et chaque pays, il y a maintenant 500 individus. Vous attribuerez aux 500 individus leurs classes ( c_{i,parent}) conformément aux distributions trouvées précédemment. Par exemple, si (P(c_{i,parent}=8|c_{i,child}=5,\rho_j=0.9) = 0.03) , alors vous assignerez la classe (c_{i,parent} = 8) à 15 des 500 individus du pays ( j) ayant (c_{i,child}=5) , car 500*0.03 = 15. Éventuellement et pour éviter toute confusion, effacez la variable (c_{i,child}) : nous n'en avons pas besoin pour la mission 4. Assurez-vous que votre nouvel échantillon contiennent bien les variables initialement présentes dans la World Income Distribution : (m_j) et (G_j) . Utilisez ce nouvel échantillon pour la mission 4.

Mission 4 Pour cette mission 4, nous chercherons à expliquer le revenu des individus en fonction de plusieurs variables explicatives : le pays de l'individu, l'indice de Gini de ce pays, la classe de revenus des parents, etc.

Appliquez une ANOVA sur vos données, en n’incluant comme variable explicative que le pays de l’individu. Analysez la performance du modèle.

Pour chacune des régressions suivantes, vous testerez 2 version : l'une en exprimant le revenu moyen du pays et les revenus (parents & enfants) en logarithme (ln), l'autre en les laissant tels quels. Vous choisirez la version la plus performante pour répondre aux question.

Appliquez une régression linéaire sur vos données, en incluant comme variables explicatives uniquement le revenu moyen du pays de l’individu et l’indice de Gini du pays de l’individu. Quel est le pourcentage de variance expliquée par votre modèle ?

Selon ce modèle, donnez la décomposition de variance totale expliquée par :

le pays de naissance (ie. le revenu moyen et l’indice de Gini) ; les autres facteurs non considérés dans le modèle (efforts, chance, etc.). Améliorez le modèle précédent en incluant maintenant la classe de revenu des parents. Quel est le pourcentage de variance expliquée par ce nouveau modèle ?

En observant le coefficient de régression associé à l’indice de Gini, peut-on affirmer que le fait de vivre dans un pays plus inégalitaire favorise plus de personnes qu’il n’en défavorise ?

Selon ce dernier modèle, donnez la décomposition de variance totale expliquée par :

le pays de naissance et le revenu des parents les autres facteurs non considérés dans le modèle (efforts, chance, etc.)

Livrables Voici les livrables attendus, à transmettre dans une archive .zip :

le code Python ou R permettant de répondre à l'ensemble de vos missions. Puisqu'il y a beaucoup de questions, faites attention à ce que votre code soit clair, qu'il délimite bien les différentes parties et questions, et qu'il soit correctement commenté ; les graphiques générés, dans un format image .png ou .jpg Pour faciliter votre passage au jury, déposez sur la plateforme, dans un dossier nommé “P7_nom_prenom”, tous les livrables du projet. Chaque livrable doit être nommé avec le numéro du projet et selon l'ordre dans lequel il apparaît, par exemple “P7_01_code”, “P7_02_graphiques”, et ainsi de suite.

Soutenance Pour chacune des missions proposées, vous détaillerez votre démarche, en précisant les éventuels problèmes rencontrés (ainsi que la manière dont vous y avez fait face) et en répondant à toutes les questions posées dans l'énoncé. La soutenance durera environ 25 minutes, avec 5 à 10 minutes de questions-réponses éventuelles.

Annexe : code Voici le code évoqué dans la mission 3, libre à vous de l'utiliser ou pas :

import scipy.stats as st import pandas as pd import numpy as np from collections import Counter

def generate_incomes(n, pj): # On génère les revenus des parents (exprimés en logs) selon une loi normale. # La moyenne et variance n'ont aucune incidence sur le résultat final (ie. sur le caclul de la classe de revenu) ln_y_parent = st.norm(0,1).rvs(size=n) # Génération d'une réalisation du terme d'erreur epsilon residues = st.norm(0,1).rvs(size=n) return np.exp(pj*ln_y_parent + residues), np.exp(ln_y_parent)

def quantiles(l, nb_quantiles): size = len(l) l_sorted = l.copy() l_sorted = l_sorted.sort_values() quantiles = np.round(np.arange(1, nb_quantiles+1, nb_quantiles/size) -0.5 +1./size) q_dict = {a:int(b) for a,b in zip(l_sorted,quantiles)} return pd.Series([q_dict[e] for e in l])

def compute_quantiles(y_child, y_parents, nb_quantiles): y_child = pd.Series(y_child) y_parents = pd.Series(y_parents) c_i_child = quantiles(y_child, nb_quantiles) c_i_parent = quantiles(y_parents, nb_quantiles) sample = pd.concat([y_child, y_parents, c_i_child, c_i_parent], axis=1) sample.columns = ["y_child", "y_parents", "c_i_child","c_i_parent"] return sample

def distribution(counts, nb_quantiles): distrib = [] total = counts["counts"].sum()

if total == 0 :
    return [0] * nb_quantiles

for q_p in range(1, nb_quantiles+1):
    subset = counts[counts.c_i_parent == q_p]
    if len(subset):
        nb = subset["counts"].values[0]
        distrib += [nb / total]
    else:
        distrib += [0]
return distrib   

def conditional_distributions(sample, nb_quantiles): counts = sample.groupby(["c_i_child","c_i_parent"]).apply(len) counts = counts.reset_index() counts.columns = ["c_i_child","c_i_parent","counts"]

mat = []
for child_quantile in np.arange(nb_quantiles)+1:
    subset = counts[counts.c_i_child == child_quantile]
    mat += [distribution(subset, nb_quantiles)]
return np.array(mat) 

def plot_conditional_distributions(p, cd, nb_quantiles): plt.figure()

# La ligne suivante sert à afficher un graphique en "stack bars", sur ce modèle : https://matplotlib.org/gallery/lines_bars_and_markers/bar_stacked.html
cumul = np.array([0] * nb_quantiles)

for i, child_quantile in enumerate(cd):
    plt.bar(np.arange(nb_quantiles)+1, child_quantile, bottom=cumul, width=0.95, label = str(i+1) +"e")
    cumul = cumul + np.array(child_quantile)

plt.axis([.5, nb_quantiles*1.3 ,0 ,1])
plt.title("p=" + str(p))
plt.legend()
plt.xlabel("quantile parents")
plt.ylabel("probabilité du quantile enfant")
plt.show()

def proba_cond(c_i_parent, c_i_child, mat): return mat[c_i_child, c_i_parent]

pj = 0.9 # coefficient d'élasticité du pays j nb_quantiles = 100 # nombre de quantiles (nombre de classes de revenu) n = 1000*nb_quantiles # taille de l'échantillon

y_child, y_parents = generate_incomes(n, pj) sample = compute_quantiles(y_child, y_parents, nb_quantiles) cd = conditional_distributions(sample, nb_quantiles) #plot_conditional_distributions(pj, cd, nb_quantiles) # Cette instruction prendra du temps si nb_quantiles > 10 print(cd)

c_i_child = 5 c_i_parent = 8 p = proba_cond(c_i_parent, c_i_child, cd) print("\nP(c_i_parent = {} | c_i_child = {}, pj = {}) = {}".format(c_i_parent, c_i_child, pj, p))

Book Recommender System Using Sci-kit learn N-neighbours

Model-Based-Recommender-Engine I created a book Recommender System using Sci-kit learn's N-neighbours algorithm for my model and the streamlit library

1 Jan 13, 2022
vortex particles for simulating smoke in 2d

vortex-particles-method-2d vortex particles for simulating smoke in 2d -vortexparticles_s

12 Aug 23, 2022
pymc-learn: Practical Probabilistic Machine Learning in Python

pymc-learn: Practical Probabilistic Machine Learning in Python Contents: Github repo What is pymc-learn? Quick Install Quick Start Index What is pymc-

pymc-learn 196 Dec 07, 2022
🌲 Implementation of the Robust Random Cut Forest algorithm for anomaly detection on streams

🌲 Implementation of the Robust Random Cut Forest algorithm for anomaly detection on streams

Real-time water systems lab 416 Jan 06, 2023
YouTube Spam Detection with python

YouTube Spam Detection This code deletes spam comment on youtube videos based on two characteristics (currently) If the author of the comment has a se

MohamadReza Taalebi 5 Sep 27, 2022
Machine Learning Algorithms ( Desion Tree, XG Boost, Random Forest )

implementation of machine learning Algorithms such as decision tree and random forest and xgboost on darasets then compare results for each and implement ant colony and genetic algorithms on tsp map,

Mohamadreza Rezaei 1 Jan 19, 2022
This is an auto-ML tool specialized in detecting of outliers

Auto-ML tool specialized in detecting of outliers Description This tool will allows you, with a Dash visualization, to compare 10 models of machine le

1 Nov 03, 2021
Automated Machine Learning Pipeline with Feature Engineering and Hyper-Parameters Tuning

The mljar-supervised is an Automated Machine Learning Python package that works with tabular data. I

MLJAR 2.4k Jan 02, 2023
Factorization machines in python

Factorization Machines in Python This is a python implementation of Factorization Machines [1]. This uses stochastic gradient descent with adaptive re

Corey Lynch 892 Jan 03, 2023
Predicting job salaries from ads - a Kaggle competition

Predicting job salaries from ads - a Kaggle competition

Zygmunt Zając 57 Oct 23, 2020
🚪✊Knock Knock: Get notified when your training ends with only two additional lines of code

Knock Knock A small library to get a notification when your training is complete or when it crashes during the process with two additional lines of co

Hugging Face 2.5k Jan 07, 2023
A mindmap summarising Machine Learning concepts, from Data Analysis to Deep Learning.

A mindmap summarising Machine Learning concepts, from Data Analysis to Deep Learning.

Daniel Formoso 5.7k Dec 30, 2022
Predict the output which should give a fair idea about the chances of admission for a student for a particular university

Predict the output which should give a fair idea about the chances of admission for a student for a particular university.

ArvindSandhu 1 Jan 11, 2022
BigDL: Distributed Deep Learning Framework for Apache Spark

BigDL: Distributed Deep Learning on Apache Spark What is BigDL? BigDL is a distributed deep learning library for Apache Spark; with BigDL, users can w

4.1k Jan 09, 2023
AutoTabular automates machine learning tasks enabling you to easily achieve strong predictive performance in your applications.

AutoTabular automates machine learning tasks enabling you to easily achieve strong predictive performance in your applications. With just a few lines of code, you can train and deploy high-accuracy m

Robin 55 Dec 27, 2022
Scikit-Learn useful pre-defined Pipelines Hub

Scikit-Pipes Scikit-Learn useful pre-defined Pipelines Hub Usage: Install scikit-pipes It's advised to install sklearn-genetic using a virtual env, in

Rodrigo Arenas 1 Apr 26, 2022
PyPOTS - A Python Toolbox for Data Mining on Partially-Observed Time Series

A python toolbox/library for data mining on partially-observed time series, supporting tasks of forecasting/imputation/classification/clustering on incomplete multivariate time series with missing va

Wenjie Du 179 Dec 31, 2022
Decentralized deep learning in PyTorch. Built to train models on thousands of volunteers across the world.

Hivemind: decentralized deep learning in PyTorch Hivemind is a PyTorch library to train large neural networks across the Internet. Its intended usage

1.3k Jan 08, 2023
DistML is a Ray extension library to support large-scale distributed ML training on heterogeneous multi-node multi-GPU clusters

DistML is a Ray extension library to support large-scale distributed ML training on heterogeneous multi-node multi-GPU clusters

27 Aug 19, 2022