import warnings
def fxn():
warnings.warn("deprecated", DeprecationWarning)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
fxn()
# importations de modules "local"
import sys
sys.path.append('functions/')
import base_notebook_light
import css_base_light
import fonctions_perso
import css_regression
import fonction_regression_lineaire
# import des librairies et des paramètres
from base_notebook_light import *
from css_base_light import *
from css_regression import *
# repère de début de traitement pour calculer le temps tital d'exécution du notebook
start_time_m4 = time.time()
# import des données
dcf = pd.read_csv("data/exports/dc_anova.csv")
# taille du df
dcf.shape
# préparation des données
dcf = dcf[['code_pays', 'pays', 'pop', 'Gj', 'gdp', 'income_avg', 'y_child', 'pj', 'c_i_parent']]
dcf.columns = ['code_pays', 'pays', 'pop', 'gini', 'gdp', 'y_child_avg', 'y_child', 'elas', 'c_i_parent']
dcf['ln_y_child'] = np.log(dcf['y_child'])
dcf['ln_y_child_avg'] = np.log(dcf['y_child_avg'])
# affichage aléatoire de 2 observations
dcf.sample(2)
(5750000, 11)
code_pays | pays | pop | gini | gdp | y_child_avg | y_child | elas | c_i_parent | ln_y_child | ln_y_child_avg | |
---|---|---|---|---|---|---|---|---|---|---|---|
2486982 | ISL | Islande | 310856.0 | 0.2851 | 36527.0 | 26888.511518 | 30282.238 | 0.200000 | 98.0 | 10.318317 | 10.199454 |
2595861 | ITA | Italie | 58922109.0 | 0.3173 | 28170.0 | 14925.214922 | 26592.664 | 0.487737 | 89.0 | 10.188391 | 9.610807 |
code_pays
: code international iso-3pays
: nom du pays en françaispop
: nombre d'habitants du paysgini
: indice de gini du paysgdp
: PIB/hab en $PPAy_child_avg
: revenu moyen des enfantsy_child
: revenu enfant par quantile c_i_parentelas
: coef d'élasticité du paysc_i_parent
: centile de revenu parentln_y_child
: logarithme de y_childln_y_child_avg
: logarithme de y_child_avgOn applique la même logique que pour la régression à 2 variables explicatives :
-> on teste la performance des 2 modèles (modèle linéaire et modèle logarithmique) et on choisit celui qui explique le plus la variance totale
--> donc celui qui a le $R^2$ le plus élevé
Remarque :
fonction_regression_lineaire
présent dans le dossier 'functions'hypotheses_regression_lineaire
qui permet de vérifier les hypothèses d'application d'une régression linéaire :analyse_reg
qui test le modèle et évalue sa performanceoutliers
qui permet de déterminer les valeurs atypiques et influentes :Equation du modèle dans le cadre linéaire :
$$\large \text{y_child}_j\: = \: \beta_0\: +\: \beta_1\, \text{y_child_avg}_j\: +\: \beta_2\, \text{gini}_j\: +\: \beta_3\, \text{c_i_parent}_j\: + \epsilon_j$$
Equation du modèle dans le cadre logarithmique :
$$\large \text{log(y_child)}_j\: = \: \beta_0\: +\: \beta_1\, \text{log(y_child_avg)}_j\: +\: \beta_2\, \text{gini}_j\: +\: \beta_3\, \text{c_i_parent}_j\: + \epsilon_j$$
avec :
# import des fonctions du module de régression
from fonction_regression_lineaire import *
# copie du df principal
df = dcf.copy()
# modèle linéaire
y_lin = 'y_child'
X_lin = ['y_child_avg', 'gini', 'c_i_parent']
xlin = "+".join(X_lin)
mod_lin=y_lin+"~"+xlin
# modèle log
y_log = 'ln_y_child'
X_log = ['ln_y_child_avg', 'gini', 'c_i_parent']
xlog = "+".join(X_log)
mod_log=y_log+"~"+xlog
version_log="3_var_explicatives_log"
# modèle linéaire
y_lin = 'y_child'
X_lin = ['y_child_avg', 'gini', 'c_i_parent']
xlin = "+".join(X_lin)
mod_lin=y_lin+"~"+xlin
# regression
res_model_lin = ols(mod_lin, data=df).fit()
# test et analyse de la régression
res_reg_lin = analyse_reg(res_model_lin, details=None)
Dep. Variable: | y_child | R-squared: | 0.523 |
---|---|---|---|
Model: | OLS | Adj. R-squared: | 0.523 |
Method: | Least Squares | F-statistic: | 2.098e+06 |
Date: | Fri, 18 Jun 2021 | Prob (F-statistic): | 0.00 |
Time: | 22:21:41 | Log-Likelihood: | -5.8603e+07 |
No. Observations: | 5750000 | AIC: | 1.172e+08 |
Df Residuals: | 5749996 | BIC: | 1.172e+08 |
Df Model: | 3 | ||
Covariance Type: | nonrobust |
La p_value est inférieure au seuil de 5% => Le modèle est significatif au niveau global
coef | std err | t | P>|t| | [0.025 | 0.975] | |
---|---|---|---|---|---|---|
Intercept | -2606.6932 | 14.383 | -181.237 | 0.000 | -2634.883 | -2578.503 |
y_child_avg | 1.0000 | 0.000 | 2291.830 | 0.000 | 0.999 | 1.001 |
gini | -1.1524 | 32.091 | -0.036 | 0.971 | -64.050 | 61.745 |
c_i_parent | 51.6295 | 0.093 | 552.970 | 0.000 | 51.447 | 51.813 |
Certaines p_values sont supérieures ou égales à 0.05 => certaines variables ne sont donc significatives
df | sum_sq | mean_sq | F | PR(>F) | |
---|---|---|---|---|---|
y_child_avg | 1.0 | 2.496311e+14 | 2.496311e+14 | 5.986933e+06 | 0.0 |
gini | 1.0 | 6.139245e-13 | 6.139245e-13 | 1.472383e-20 | 1.0 |
c_i_parent | 1.0 | 1.274962e+13 | 1.274962e+13 | 3.057757e+05 | 0.0 |
Residual | 5749996.0 | 2.397518e+14 | 4.169599e+07 | NaN | NaN |
=> comme pour la régression précédente avec 2 variables explicatives, la variable indice de Gini
n'est pas significative
Le modèle explique 53% de la variance totale des revenus
On va effectuer une nouvelle régression linéaire, en utilisant les logarithmes
# modèle logarithmique
y = 'ln_y_child'
X = ['ln_y_child_avg', 'gini', 'c_i_parent']
xlog = "+".join(X)
mod_log=y+"~"+xlog
# regression
res_model_log = ols(mod_log, data=df).fit()
# test et analyse de la régression
res_reg_log = analyse_reg(res_model_log, details=None)
Dep. Variable: | ln_y_child | R-squared: | 0.781 |
---|---|---|---|
Model: | OLS | Adj. R-squared: | 0.781 |
Method: | Least Squares | F-statistic: | 6.836e+06 |
Date: | Fri, 18 Jun 2021 | Prob (F-statistic): | 0.00 |
Time: | 22:21:44 | Log-Likelihood: | -5.6312e+06 |
No. Observations: | 5750000 | AIC: | 1.126e+07 |
Df Residuals: | 5749996 | BIC: | 1.126e+07 |
Df Model: | 3 | ||
Covariance Type: | nonrobust |
La p_value est inférieure au seuil de 5% => Le modèle est significatif au niveau global
coef | std err | t | P>|t| | [0.025 | 0.975] | |
---|---|---|---|---|---|---|
Intercept | -0.0999 | 0.003 | -38.349 | 0.000 | -0.105 | -0.095 |
ln_y_child_avg | 0.9861 | 0.000 | 4046.589 | 0.000 | 0.986 | 0.987 |
gini | -1.6351 | 0.003 | -526.227 | 0.000 | -1.641 | -1.629 |
c_i_parent | 0.0112 | 9.32e-06 | 1200.661 | 0.000 | 0.011 | 0.011 |
Toutes les p_values sont inférieures à 0.05 => toutes les variables sont significatives
df | sum_sq | mean_sq | F | PR(>F) | |
---|---|---|---|---|---|
ln_y_child_avg | 1.0 | 7.800125e+06 | 7.800125e+06 | 1.879052e+07 | 0.0 |
gini | 1.0 | 1.149342e+05 | 1.149342e+05 | 2.768768e+05 | 0.0 |
c_i_parent | 1.0 | 5.984170e+05 | 5.984170e+05 | 1.441588e+06 | 0.0 |
Residual | 5749996.0 | 2.386878e+06 | 4.151096e-01 | NaN | NaN |
print(*res_reg_log)
regression_summary regression_test_global synth_perf_glob regression_test_variables synth_perf_var anova_decomposition_variance synth_var_expl coef equation_lineaire
res_reg_log['synth_var_expl']
'Le modèle de régression linéaire explique plus de 78% de la variance totale'
Toutes les variables explicatives sont significatives et ce modèle explique près de 78% de la variance totale
version_name = "3_var_log"
hyp_reg_log = hypotheses_regression_lineaire(y, X, df, version_name, details=None)
valeurs_reelles | valeurs_predites | residus | |
---|---|---|---|
705507 | 5.004370 | 5.598458 | -0.594088 |
4248006 | 9.863347 | 7.925396 | 1.937951 |
491434 | 9.156045 | 8.991307 | 0.164739 |
1327638 | 9.662478 | 9.418913 | 0.243564 |
1367283 | 7.371434 | 7.645321 | -0.273887 |
=> si linéarité, alors les points de la droite "prédictions / valeurs réelles" devraient suivre la droite d'équation y=x
pearson | p-value | |
---|---|---|
gini__c_i_parent | 0.000015 | 0.971967 |
ln_y_child_avg__c_i_parent | 0.000055 | 0.894622 |
ln_y_child_avg__gini | -0.261327 | 0.000000 |
feature | VIF | |
---|---|---|
0 | ln_y_child_avg | 1.073297 |
1 | gini | 1.073297 |
2 | c_i_parent | 1.000000 |
Interprétation des tests :
Jarque-Bera test ---- statistic: 1805609.6352, p-value: 0.0 Kolmogorov-Smirnov test ---- statistic: 0.1277, p-value: 0.0000
Les 2 tests conduisent à rejeter H0 : on en conclue que les données ne suivent pas une loi normale
Interprétation des tests :
Breusch Pagan test ---- p-value: 0.0
La p_value est inférieure au seuil de signification de 5% : on rejette l'hypothèse H0 d'homoscédasticité des résidus => les variances ne sont pas constantes
print(*hyp_reg_log)
res_modelisation df_y_y_pred_residus graph_hyp_linearite synth_linearite paires_corr_croisees r2 VIF synth_coli synth_normalite graph_distribution_residus graph_prediction_vs__residus synth_homo
res_outlier_log = outliers(y, X, df, res_model_log, version_name, details=None, nb_pays_graph=2, graph_france=False)
code_pays | pays | pop | gini | gdp | y_child_avg | y_child | elas | c_i_parent | ln_y_child | ln_y_child_avg | obs | levier | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3534451 | MLI | Mali | 14113577.0 | 0.3303 | 929.52966 | 681.075039 | 739.58075 | 0.713953 | 91.0 | 6.606083 | 6.523672 | 3534452 | 9.995673e-07 |
2213918 | IDN | Indonésie | 235469762.0 | 0.3721 | 3689.00000 | 1334.618297 | 724.11096 | 0.500000 | 75.0 | 6.584945 | 7.196401 | 2213919 | 4.222380e-07 |
5280957 | TZA | République-Unie de Tanzanie | 41853944.0 | 0.3757 | 1201.00000 | 588.766986 | 539.94430 | 0.511973 | 91.0 | 6.291466 | 6.378030 | 5280958 | 9.445830e-07 |
pays Afrique du Sud 50000 Honduras 31943 Colombie 7967 République Centrafricaine 5965 République Démocratique du Congo 5941 Guatemala 4005 Kenya 3991 États-Unis 3949 Bolivie 2973 Chili 1984 dtype: int64
graph_leviers(y, X, res_model, df, pays)avec pays le nom du pays souhaité (ne pas modifier les autres paramètres)
code_pays | pays | pop | gini | gdp | y_child_avg | y_child | elas | c_i_parent | ln_y_child | ln_y_child_avg | obs | levier | res_stud | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
4439205 | PRT | Portugal | 10595314.0 | 0.3617 | 21956.0 | 10098.675366 | 12972.1080 | 0.282375 | 49.0 | 9.470557 | 9.220160 | 4439206 | 3.441537e-07 | 0.809660 |
1336437 | DNK | Danemark | 5497729.0 | 0.2599 | 34130.0 | 17043.146491 | 19121.1070 | 0.145146 | 90.0 | 9.858548 | 9.743503 | 1336438 | 1.034130e-06 | -0.359294 |
5041941 | SYR | République Arabe Syrienne | 20664038.0 | 0.3576 | 4512.0 | 685.817495 | 999.1198 | 0.500000 | 94.0 | 6.906875 | 6.530612 | 5041942 | 9.629560e-07 | 0.155426 |
pays Afrique du Sud 14253 Honduras 10831 Bolivie 8864 Brésil 7329 Colombie 6957 Chine 6938 Mexique 6142 Nicaragua 6120 Panama 6107 Paraguay 6042 dtype: int64
graph_res_stud(y, X, res_model, df, pays)avec pays le nom du pays souhaité (ne pas modifier les autres paramètres)
code_pays | pays | pop | gini | gdp | y_child_avg | y_child | elas | c_i_parent | ln_y_child | ln_y_child_avg | obs | levier | res_stud | dis_cooks | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2109049 | HRV | Croatie | 4.352636e+06 | 0.3028 | 17219.0 | 7716.465790 | 4184.8247 | 0.464077 | 7.0 | 8.339220 | 8.951112 | 2109050 | 7.489219e-07 | 0.045181 | 3.822038e-10 |
1932074 | GIN | Guinée | 9.738792e+06 | 0.3963 | 977.0 | 696.012013 | 672.9343 | 0.342855 | 22.0 | 6.511648 | 6.545367 | 1932075 | 6.684724e-07 | 0.867607 | 1.257968e-07 |
891593 | CHN | Chine | 1.383986e+09 | 0.4783 | 5712.0 | 2522.758726 | 4306.9146 | 0.399000 | 32.0 | 8.367977 | 7.833108 | 891594 | 4.575923e-07 | 1.812352 | 3.757544e-07 |
pays Afrique du Sud 28579 Honduras 19386 Bolivie 12514 Colombie 11388 Brésil 10977 République Centrafricaine 10628 Guatemala 9043 Panama 9013 États-Unis 8726 Chili 8682 dtype: int64
graph_distance_cook(y, X, res_model, df, pays)avec pays le nom du pays souhaité (ne pas modifier les autres paramètres)
Soit le df "analyses_values" qui ne comptabilise que les données hors seuils (affichage aléatoire de 10 observations)
code_pays | pays | pop | gini | gdp | y_child_avg | y_child | elas | c_i_parent | ln_y_child | ln_y_child_avg | obs | levier | res_stud | dis_cooks | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
5161803 | TLS | Timor-Leste | 1055431.0 | 0.3198 | 1113.1322 | 727.610395 | 419.76935 | 0.701994 | 44.0 | 6.039705 | 6.589766 | 5161804 | NaN | NaN | NaN |
1714095 | FRA | France | 62209207.0 | 0.3291 | 30357.0000 | 18309.407545 | 11296.75200 | 0.357105 | 17.0 | 9.332271 | 9.815170 | 1714096 | NaN | NaN | NaN |
3105188 | LTU | Lituanie | 3212865.0 | 0.3345 | 17571.0000 | 6623.656565 | 2452.75780 | 0.400000 | 23.0 | 7.804968 | 8.798403 | 3105189 | NaN | NaN | NaN |
5226999 | TUR | Turquie | 70418604.0 | 0.4220 | 11904.0000 | 6050.465331 | 4928.42800 | 0.500000 | 100.0 | 8.502775 | 8.707890 | 5227000 | NaN | NaN | NaN |
1428860 | ECU | Équateur | 14535739.0 | 0.5099 | 7560.0000 | 3383.741001 | 2460.06980 | 1.029957 | 71.0 | 7.807945 | 8.126737 | 1428861 | NaN | NaN | NaN |
175549 | AUT | Autriche | 8341532.0 | 0.2783 | 36193.0000 | 16637.600204 | 14875.32900 | 0.245267 | 11.0 | 9.607459 | 9.719420 | 175550 | NaN | NaN | NaN |
5318820 | UGA | Ouganda | 30431736.0 | 0.4269 | 1067.0000 | 987.206289 | 562.67206 | 1.029195 | 52.0 | 6.332697 | 6.894879 | 5318821 | NaN | NaN | NaN |
3062193 | LKA | Sri Lanka | 19983984.0 | 0.4022 | 4202.5703 | 1877.940244 | 898.82410 | 0.500000 | 29.0 | 6.801087 | 7.537931 | 3062194 | NaN | NaN | NaN |
5213314 | TUR | Turquie | 70418604.0 | 0.4220 | 11904.0000 | 6050.465331 | 2739.89400 | 0.500000 | 50.0 | 7.915675 | 8.707890 | 5213315 | NaN | NaN | NaN |
4158192 | PAK | Pakistan | 171648986.0 | 0.2999 | 2335.0000 | 887.839279 | 486.23578 | 0.450500 | 25.0 | 6.186694 | 6.788791 | 4158193 | NaN | NaN | NaN |
Soit le df "pays_outliers", df synthétique final des outliers
-> on affiche les données pour les 15 pays avec le plus d'outliers
levier | res_stud | dis_cooks | somme_outliers | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
code_pays | pays | pop | gini | gdp | y_child_avg | elas | ln_y_child_avg | ||||
ZAF | Afrique du Sud | 4.977947e+07 | 0.6698 | 9602.00000 | 5617.904880 | 0.677000 | 8.633714 | 50000 | 14253 | 28579 | 92832 |
HND | Honduras | 7.980955e+06 | 0.6017 | 3628.00000 | 3296.268419 | 0.660000 | 8.100546 | 31943 | 10831 | 19386 | 62160 |
COL | Colombie | 4.425498e+07 | 0.5693 | 8185.00000 | 3547.005276 | 1.095440 | 8.173859 | 7967 | 6957 | 11388 | 26312 |
BOL | Bolivie | 9.721454e+06 | 0.5615 | 3950.00000 | 3016.263843 | 0.866268 | 8.011774 | 2973 | 8864 | 12514 | 24351 |
CAF | République Centrafricaine | 4.273366e+06 | 0.5617 | 685.00000 | 811.299901 | 0.660000 | 6.698638 | 5965 | 5927 | 10628 | 22520 |
BRA | Brésil | 1.920304e+08 | 0.5445 | 9559.00000 | 4807.484594 | 0.635000 | 8.477929 | 992 | 7329 | 10977 | 19298 |
GTM | Guatemala | 1.400643e+07 | 0.5683 | 4367.00000 | 2142.474753 | 1.015206 | 7.669717 | 4005 | 5531 | 9043 | 18579 |
USA | États-Unis | 3.034860e+08 | 0.4318 | 43261.00000 | 25503.581661 | 0.537666 | 10.146574 | 3949 | 5008 | 8726 | 17683 |
CHL | Chili | 1.670826e+07 | 0.5316 | 13390.00000 | 7051.609966 | 0.570000 | 8.861011 | 1984 | 5375 | 8682 | 16041 |
PAN | Panama | 3.516204e+06 | 0.5319 | 11767.00000 | 5135.139376 | 0.966865 | 8.543862 | 0 | 6107 | 9013 | 15120 |
COD | République Démocratique du Congo | 6.041120e+07 | 0.4440 | 303.19305 | 276.016044 | 0.707703 | 5.620459 | 5941 | 2767 | 6047 | 14755 |
PRY | Paraguay | 6.081296e+06 | 0.5251 | 4347.00000 | 3278.080965 | 0.660000 | 8.095013 | 0 | 6042 | 7161 | 13203 |
MEX | Mexique | 1.108153e+08 | 0.5080 | 13434.00000 | 3885.830277 | 0.660000 | 8.265092 | 0 | 6142 | 6618 | 12760 |
CHN | Chine | 1.383986e+09 | 0.4783 | 5712.00000 | 2522.758726 | 0.399000 | 7.833108 | 0 | 6938 | 4442 | 11380 |
NIC | Nicaragua | 5.667432e+06 | 0.4828 | 2576.00000 | 2519.333262 | 0.660000 | 7.831750 | 0 | 6120 | 4718 | 10838 |
Ainsi,
print(*res_outlier_log)
seuil_levier graph_leviers_glob df_pays_leviers_strict liste_pays_leviers_strict df_pays_leviers_large liste_pays_leviers_large graph_leviers_pays_Afrique_du_Sud graph_leviers_pays_Honduras seuil_res_stud graph_résidus_glob pays_res_stud graph_residus_pays_Afrique_du_Sud graph_residus_pays_Honduras seuil_cooks influentes graph_cooks_glob graph_cooks_pays_Afrique_du_Sud graph_cooks_pays_Honduras df_synthese_valeurs_outliers df_synthese_pays_nb_outliers
Nous allons traiter les valeurs atypiques et influentes détectées
Méthode :
on supprime les observations qui contiennent des valeurs atypiques ET des valeurs influentes :
-> 2 cas différents possibles :
# df des valeurs des outliers
res = res_outlier_log["df_synthese_valeurs_outliers"]
# valeurs des différents seuils
seuil_levier = res_outlier_log['seuil_levier']
seuil_res_stud = res_outlier_log['seuil_res_stud']
seuil_cooks = res_outlier_log['seuil_cooks']
# suppression des observations selon la condition suivante
condition1 = (res['dis_cooks'] > seuil_cooks) & (res['levier'] > seuil_levier)
condition2 = (res['dis_cooks'] > seuil_cooks) & ((res['res_stud'] > seuil_res_stud) | (res['res_stud'] < -seuil_res_stud))
condition = condition1 | condition2
# df des valeurs gardées
res_traitement_outliers = res[~condition]
# calcul du nombre de valeurs supprimées
nb_val_suppr = res.shape[0] - res_traitement_outliers.shape[0]
part_val_suppr = round(nb_val_suppr/res.shape[0],2)
print(f"Nombre d'outliers supprimés : {nb_val_suppr}, soit {part_val_suppr}% du dataset")
Nombre d'outliers supprimés : 257712, soit 0.04% du dataset
# régression linéaire
res_model = ols(mod_log, data=res_traitement_outliers).fit()
# performance du modèle
anal_reg_traitement_outliers = analyse_reg(res_model, details=None)
Dep. Variable: | ln_y_child | R-squared: | 0.839 |
---|---|---|---|
Model: | OLS | Adj. R-squared: | 0.839 |
Method: | Least Squares | F-statistic: | 9.549e+06 |
Date: | Fri, 18 Jun 2021 | Prob (F-statistic): | 0.00 |
Time: | 22:27:10 | Log-Likelihood: | -4.3497e+06 |
No. Observations: | 5492288 | AIC: | 8.699e+06 |
Df Residuals: | 5492284 | BIC: | 8.700e+06 |
Df Model: | 3 | ||
Covariance Type: | nonrobust |
La p_value est inférieure au seuil de 5% => Le modèle est significatif au niveau global
coef | std err | t | P>|t| | [0.025 | 0.975] | |
---|---|---|---|---|---|---|
Intercept | -0.1581 | 0.002 | -70.018 | 0.000 | -0.162 | -0.154 |
ln_y_child_avg | 0.9976 | 0.000 | 4811.246 | 0.000 | 0.997 | 0.998 |
gini | -1.5305 | 0.003 | -550.866 | 0.000 | -1.536 | -1.525 |
c_i_parent | 0.0097 | 7.98e-06 | 1213.739 | 0.000 | 0.010 | 0.010 |
Toutes les p_values sont inférieures à 0.05 => toutes les variables sont significatives
df | sum_sq | mean_sq | F | PR(>F) | |
---|---|---|---|---|---|
ln_y_child_avg | 1.0 | 7.668679e+06 | 7.668679e+06 | 2.687196e+07 | 0.0 |
gini | 1.0 | 8.602053e+04 | 8.602053e+04 | 3.014261e+05 | 0.0 |
c_i_parent | 1.0 | 4.204089e+05 | 4.204089e+05 | 1.473162e+06 | 0.0 |
Residual | 5492284.0 | 1.567380e+06 | 2.853785e-01 | NaN | NaN |
version_name="3_var_log_sans_outliers"
verif_hyp_traitement_outliers = hypotheses_regression_lineaire(y, X, res_traitement_outliers, version_name, details=None)
valeurs_reelles | valeurs_predites | residus | |
---|---|---|---|
1526994 | 9.404545 | 9.789517 | -0.384972 |
2992147 | 7.262686 | 6.659497 | 0.603189 |
1624149 | 9.543080 | 9.394667 | 0.148412 |
2814751 | 6.946335 | 7.202263 | -0.255928 |
2170245 | 8.497551 | 8.563537 | -0.065986 |
=> si linéarité, alors les points de la droite "prédictions / valeurs réelles" devraient suivre la droite d'équation y=x
pearson | p-value | |
---|---|---|
gini__c_i_parent | 0.000379 | 3.742117e-01 |
ln_y_child_avg__c_i_parent | 0.003808 | 4.518575e-19 |
ln_y_child_avg__gini | -0.283138 | 0.000000e+00 |
feature | VIF | |
---|---|---|
0 | ln_y_child_avg | 1.087172 |
1 | gini | 1.087157 |
2 | c_i_parent | 1.000017 |
Interprétation des tests :
Jarque-Bera test ---- statistic: 7111.1947, p-value: 0.0 Kolmogorov-Smirnov test ---- statistic: 0.1468, p-value: 0.0000
Les 2 tests conduisent à rejeter H0 : on en conclue que les données ne suivent pas une loi normale
Interprétation des tests :
Breusch Pagan test ---- p-value: 0.0
La p_value est inférieure au seuil de signification de 5% : on rejette l'hypothèse H0 d'homoscédasticité des résidus => les variances ne sont pas constantes
=> En supprimant seulement 0.04% des valeurs initiales, la variance des revenus expliquée par le modèle passe de 77.70% à 84%.
Mais attention : les suppressions effectuées ici sont automatiques et donc non nécessairement judicieuses :
--> il faudrait sélectionner les suppressions (ou les remplacements des valeurs concernées par la moyenne ou la médiane ou autre) en fonction de données supplémentaires (ex : notre portefeuille client par pays)
Interprétation du coefficient $\beta_1$
Soit l'équation de régression suivante (modèle niveau-niveau) :
$ y_j = \beta_0 + \beta_1\, {X_1}_j + \beta_2\, {X_2}_j + \epsilon_j $
Soit l'équation de régression suivante (modèle log-log): $ ln(y)_j = \beta_0 + \beta_1\, ln({X_1})_j + \beta_2\, {X_2}_j + \epsilon_j $
Soit l'équation de régression suivante (modèle log-niveau): $ ln(y)_j = \beta_0 + \beta_1\, {X_1}_j + \beta_2\, {X_2}_j + \epsilon_j $
Soit l'équation de régression suivante (modèle niveau-log): $ y_j = \beta_0 + \beta_1\, ln({X_1})_j + \beta_2\, {X_2}_j + \epsilon_j $
# equation de notre modèle
res_reg_log['equation_lineaire']
'ln_y_child = -0.0999 + 0.9861(ln_y_child_avg) - 1.6351(gini) + 0.0112(c_i_parent)'
Concernant notre modèle, nous avons donc :
avec :
Ainsi, toutes choses égales par ailleurs, vivre dans un pays avec un indice de gini plus élevé de 0,1 se traduit par des revenus diminués de 16.35%.
Notion développée par l'économiste américain Alan Krueger en 2012
Concept qui illustre le lien entre le niveau d’inégalité d’un pays et son niveau d’immobilité intergénérationnelle.
ainsi, plus les inégalités de revenus sont élevées, plus la probabilité que les revenus enfants soient similaires aux revenus parents est élevée
==> cela se traduit par une corrélation positive entre l'indice de Gini d'un pays et son taux de mobilité intergénérationnelle.
Le modèle était le suivant :
elas
dans notre dataset)Gini
)Représentons la droite de régression correspondante
(nous ne retenons que les pays pour lesquels on dispose des véritables valeurs d'élasticité et non pas les valeurs ajustées selon la région mondiale)
gatsby = dcf[['code_pays', 'pays', 'gini', 'elas', 'y_child_avg']].drop_duplicates().reset_index(drop=True)
# on récupère la liste des pays avec une élasticité calculée
elas = pd.read_csv("data/exports/cp_elas_reel.csv")
# on limite les données à ces pays
gatsby_sel = gatsby[gatsby["code_pays"].isin(elas.code_pays)]
gatsby_sel.shape
gatsby_sel.sample(3)
(65, 5)
code_pays | pays | gini | elas | y_child_avg | |
---|---|---|---|---|---|
105 | TZA | République-Unie de Tanzanie | 0.3757 | 0.511973 | 588.766986 |
72 | MNG | Mongolie | 0.3581 | 0.401002 | 2338.087424 |
34 | FRA | France | 0.3291 | 0.357105 | 18309.407545 |
import plotly.express as px
df = gatsby_sel
#df.gini = df.gini.apply(lambda x: 100*x)
fig = px.scatter(
df, x='gini', y='elas', opacity=0.65,
trendline='ols', trendline_color_override='darkblue',
hover_data=['pays'], labels=dict(gini="Indice de Gini", elas="Indice de Mobilité Intergénérationelle"),
title="Courbe de \"Gatsby le Magnifique\""
)
fig.show()
path_graph = "data/exports/img_regression/"+version_name+"/"
os.makedirs(path_graph, exist_ok=True)
fig.write_html(path_graph+version_name+"0.droite_de_regression_gatsby.html")
fig.write_image(path_graph+version_name+"0.droite_de_regression_gatsby.png")
model_gatsby = ols('elas~gini', data=gatsby_sel).fit()
tt=analyse_reg(model_gatsby, details=None)
Dep. Variable: | elas | R-squared: | 0.378 |
---|---|---|---|
Model: | OLS | Adj. R-squared: | 0.368 |
Method: | Least Squares | F-statistic: | 38.30 |
Date: | Fri, 18 Jun 2021 | Prob (F-statistic): | 5.06e-08 |
Time: | 22:29:14 | Log-Likelihood: | 14.699 |
No. Observations: | 65 | AIC: | -25.40 |
Df Residuals: | 63 | BIC: | -21.05 |
Df Model: | 1 | ||
Covariance Type: | nonrobust |
La p_value est inférieure au seuil de 5% => Le modèle est significatif au niveau global
coef | std err | t | P>|t| | [0.025 | 0.975] | |
---|---|---|---|---|---|---|
Intercept | -0.0605 | 0.097 | -0.621 | 0.537 | -0.255 | 0.134 |
gini | 1.5801 | 0.255 | 6.188 | 0.000 | 1.070 | 2.090 |
Toutes les p_values sont inférieures à 0.05 => toutes les variables sont significatives
df | sum_sq | mean_sq | F | PR(>F) | |
---|---|---|---|---|---|
gini | 1.0 | 1.471737 | 1.471737 | 38.295852 | 5.063698e-08 |
Residual | 63.0 | 2.421135 | 0.038431 | NaN | NaN |
Avec les données de notre modèle, l'indice de Gini explique 38% de la variation de l'indice de mobilité intergénérationnelle
version_name="2_var_gatsby"
verif_hyp_gatsby = hypotheses_regression_lineaire('elas', ['gini'], gatsby_sel, version_name, details=None)
valeurs_reelles | valeurs_predites | residus | |
---|---|---|---|
80 | 0.303956 | 0.394272 | -0.090316 |
83 | 0.450500 | 0.413392 | 0.037108 |
58 | 0.394000 | 0.495083 | -0.101083 |
17 | 0.399000 | 0.695282 | -0.296282 |
98 | 0.259600 | 0.342287 | -0.082687 |
=> si linéarité, alors les points de la droite "prédictions / valeurs réelles" devraient suivre la droite d'équation y=x
Interprétation des tests :
Jarque-Bera test ---- statistic: 4.9915, p-value: 0.08243557943381785 Kolmogorov-Smirnov test ---- statistic: 0.3742, p-value: 0.0000
Les 2 tests conduisent à des interprétations différentes : veuillez effectuer d'autres tests pour pouvoir conclure
Interprétation des tests :
Breusch Pagan test ---- p-value: 0.2804285750098525
La p_value est supérieure ou égale au seuil de signification de 5% : on accepte l'hypothèse H0 d'homoscédasticité des résidus => les variances dont constantes
from fonctions_perso import duree_convert
# repère de fin de traitement du notebook
end_time_m4 = time.time()
duree_m4 = end_time_m4 - start_time_m4
duree = duree_convert(duree_m4)
print("Temps total d'exécution du notebook : "+str(duree))
Temps total d'exécution du notebook : 7min 42s