Apprenez APPELPY en 10 minutes - Bibliothèque d'économie métrique appliquée Python

** Apprenez en 10 minutes APPEL PY **

Cet article est une traduction japonaise de ce cahier.

import pandas as pd
import numpy as np
import statsmodels.api as sm  # for datasets
import matplotlib.pyplot as plt
%matplotlib inline

import warnings
warnings.filterwarnings('ignore')

** Présentation des fonctionnalités d'Appelpy. ** **

--L'analyse exploratoire des données --Estimation du modèle --Diagnostic de modèle

Remarque: ce notebook a été exécuté avec la dernière version d'Appelpy v0.4.2 et ses dépendances.

Paramètres du jeu de données du modèle

Explorons maintenant les fonctionnalités d'Appelpy en utilisant l'un des ensembles de données les plus riches en économie métrique. The California Test Score Data Set (** Caschool **).

Chargez l'ensemble de données avec Pandas et récupérez les données avec la méthode Statsmodels.

# Load data
df = sm.datasets.get_rdataset('Caschool', 'Ecdat').data
# Add together the two test scores (total score)
df['scrtot'] = df['readscr'] + df['mathscr']
df.head()
distcod county district grspan enrltot teachers calwpct mealpct computer testscr compstu expnstu str avginc elpct readscr mathscr scrtot
0 75119 Alameda Sunol Glen Unified KK-08 195 10.900000 0.510200 2.040800 67 690.799988 0.343590 6384.911133 17.889910 22.690001 0.000000 691.599976 690.000000 1381.599976
1 61499 Butte Manzanita Elementary KK-08 240 11.150000 15.416700 47.916698 101 661.200012 0.420833 5099.380859 21.524664 9.824000 4.583333 660.500000 661.900024 1322.400024
2 61549 Butte Thermalito Union Elementary KK-08 1550 82.900002 55.032299 76.322601 169 643.599976 0.109032 5501.954590 18.697226 8.978000 30.000002 636.299988 650.900024 1287.200012
3 61457 Butte Golden Feather Union Elementary KK-08 243 14.000000 36.475399 77.049202 85 647.700012 0.349794 7101.831055 17.357143 8.978000 0.000000 651.900024 643.500000 1295.400024
4 61523 Butte Palermo Union Elementary KK-08 1335 71.500000 33.108601 78.427002 171 640.849976 0.128090 5235.987793 18.671329 9.080333 13.857677 641.799988 639.900024 1281.700012

Inspectez les données

Maintenant que nous avons les données, examinons de plus près la distribution de certaines variables clés avant la modélisation.

Appelpy a un module ** ʻeda` ** (analyse exploratoire des données).

from appelpy.eda import statistical_moments

Obtenez tous les moments statistiques à la fois.

  1. Moyenne
  2. Distribué
  3. Distorsion (la valeur par défaut est Fisher)
  4. Netteté
statistical_moments(df)
mean var skew kurtosis
distcod 67472.8 1.20201e+07 -0.0307844 -1.09626
enrltot 2628.79 1.53124e+07 2.87017 10.2004
teachers 129.067 35311.2 2.93254 11.219
calwpct 13.246 131.213 1.68306 4.58959
mealpct 44.7052 735.678 0.183954 -0.999802
computer 303.383 194782 2.87169 10.7729
testscr 654.157 363.03 0.0916151 -0.254288
compstu 0.135927 0.00421926 0.922369 1.43113
expnstu 5312.41 401876 1.0679 1.87571
str 19.6404 3.57895 -0.0253655 0.609597
avginc 15.3166 52.2135 2.21516 6.53212
elpct 15.7682 334.375 1.4268 1.4354
readscr 654.97 404.331 -0.0583962 -0.358049
mathscr 653.343 351.72 0.255082 -0.159811
scrtot 1308.31 1452.12 0.0916149 -0.254288

Estimation du modèle

Au cœur d'Appelpy se trouve la modélisation de ce qui se passe dans l'ensemble de données.

Le module ** linear_model ** contient des classes pour la modélisation des données. Exemple: OLS (moindres carrés ordinaires)

from appelpy.linear_model import OLS

** Voici une recette pour estimer un modèle linéaire. ** **

  1. Créez deux listes, y_list et X_list, pour la variable dépendante (y) et la variable indépendante (X).
y_list = ['scrtot']
X_list = ['avginc', 'str', 'enrltot', 'expnstu']
  1. Ajustez le modèle sur une ligne en passant le bloc de données du modèle et deux listes en entrée de l'objet OLS.
model_nonrobust = OLS(df, y_list, X_list).fit()
  1. Obtenez le résultat du modèle de clé avec l'attribut model_selection_stats, y compris l'erreur de racine carrée moyenne carrée (Root MSE).
model_nonrobust.model_selection_stats
{'root_mse': 25.85923055850994,
 'r_squared': 0.5438972040191434,
 'r_squared_adj': 0.5395010324916171,
 'aic': 3929.1191674301117,
 'bic': 3949.320440986499}

Obtenez un résumé des Statsmodels avec l'attribut results_output ...

model_nonrobust.results_output
OLS Regression Results
Dep. Variable: scrtot R-squared: 0.544
Model: OLS Adj. R-squared: 0.540
Method: Least Squares F-statistic: 123.7
Date: Mon, 04 May 2020 Prob (F-statistic): 2.05e-69
Time: 18:32:26 Log-Likelihood: -1959.6
No. Observations: 420 AIC: 3929.
Df Residuals: 415 BIC: 3949.
Df Model: 4
Covariance Type: nonrobust
coef std err t P>|t| [0.025 0.975]
const 1312.9203 27.833 47.171 0.000 1258.208 1367.632
avginc 3.8640 0.185 20.876 0.000 3.500 4.228
str -1.3954 0.893 -1.563 0.119 -3.150 0.359
enrltot -0.0016 0.000 -4.722 0.000 -0.002 -0.001
expnstu -0.0061 0.003 -2.316 0.021 -0.011 -0.001
Omnibus: 7.321 Durbin-Watson: 0.763
Prob(Omnibus): 0.026 Jarque-Bera (JB): 7.438
Skew: -0.326 Prob(JB): 0.0243
Kurtosis: 2.969 Cond. No. 1.39e+05


Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.39e+05. This might indicate that there are
strong multicollinearity or other numerical problems.


... Maintenant, il est enfin facile d'obtenir les résultats d'un modèle standardisé en utilisant l'attribut results_output_standardized.


model_nonrobust.results_output_standardized
# This is a Styler object; add .data to access the underlying Pandas dataframe
Unstandardized and Standardized Estimates
coef t P>|t| coef_stdX coef_stdXy stdev_X
scrtot
avginc +3.8640 +20.876 0.000 +27.9209 +0.7327 7.2259
str -1.3954 -1.563 0.119 -2.6399 -0.0693 1.8918
enrltot -0.0016 -4.722 0.000 -6.3035 -0.1654 3913.1050
expnstu -0.0061 -2.316 0.021 -3.8364 -0.1007 633.9371

La sortie est similaire à la commande listcoef de Stata.

Diagnostic de modèle

Appelez la méthode diagnostic_plot de l'objet modèle pour afficher de nombreux diagnostics de régression visuels **: **.

--pp_plot: tracé P-P -- qq_plot: tracé Q-Q --rvp_plot: tracé des valeurs résiduelles et prédites --rvf_plot: tracé des valeurs résiduelles et mesurées

Le module ** diagnostics ** d'Appelpy a une suite de classes et de fonctions pour le diagnostic de régression.

dessin

** Voici une recette pour un ensemble 2x2 de tracés de diagnostic. ** **

fig, axarr = plt.subplots(2, 2, figsize=(10, 10))
model_nonrobust.diagnostic_plot('pp_plot', ax=axarr[0][0])
model_nonrobust.diagnostic_plot('qq_plot', ax=axarr[1][0])
model_nonrobust.diagnostic_plot('rvf_plot', ax=axarr[1][1])
axarr[0, 1].axis('off')
plt.tight_layout()

output_30_0.png

Bon chagrin. Le modèle spécifié a un problème particulier avec des scores de test supérieurs à 1350.

Il semble y avoir une variance non constante dans le graphique RVF.

Il est probablement réparti uniformément, mais faisons un test plus spécifique.

Dispersion égale

from appelpy.diagnostics import heteroskedasticity_test

Appelez l'un des nombreux ** tests d'isodispersité **. Exemple:

bp_stats = heteroskedasticity_test('breusch_pagan', model_nonrobust)
print('Breusch-Pagan test :: {}'.format(bp_stats['distribution'] + '({})'.format(bp_stats['nu'])))
print('Test statistic: {:.4f}'.format(bp_stats['test_stat']))
print('Test p-value: {:.4f}'.format(bp_stats['p_value']))
Breusch-Pagan test :: chi2(1)
Test statistic: 2.5579
Test p-value: 0.1097
bps_stats = heteroskedasticity_test('breusch_pagan_studentized', model_nonrobust)
print('Breusch-Pagan test (studentized) :: {}'.format(bps_stats['distribution'] + '({})'.format(bps_stats['nu'])))
print('Test statistic: {:.4f}'.format(bps_stats['test_stat']))
print('Test p-value: {:.4f}'.format(bps_stats['p_value']))
Breusch-Pagan test (studentized) :: chi2(1)
Test statistic: 11.3877
Test p-value: 0.0225

Le test Studentized Breusch-Pagan est considéré comme plus robuste et montre des différences significatives par rapport à l'hypothèse d'hypodispersité initiale, donc adaptons-le à un modèle avec l'erreur standard Heteroskedastic-Robust (erreur HC1). ..

model_hc1 = OLS(df, y_list, X_list, cov_type='HC1').fit()
model_hc1.results_output
OLS Regression Results
Dep. Variable: scrtot R-squared: 0.544
Model: OLS Adj. R-squared: 0.540
Method: Least Squares F-statistic: 78.60
Date: Mon, 04 May 2020 Prob (F-statistic): 1.36e-49
Time: 18:32:27 Log-Likelihood: -1959.6
No. Observations: 420 AIC: 3929.
Df Residuals: 415 BIC: 3949.
Df Model: 4
Covariance Type: HC1
coef std err z P>|z| [0.025 0.975]
const 1312.9203 29.364 44.711 0.000 1255.367 1370.474
avginc 3.8640 0.240 16.119 0.000 3.394 4.334
str -1.3954 0.932 -1.498 0.134 -3.221 0.430
enrltot -0.0016 0.000 -5.794 0.000 -0.002 -0.001
expnstu -0.0061 0.003 -2.166 0.030 -0.012 -0.001
Omnibus: 7.321 Durbin-Watson: 0.763
Prob(Omnibus): 0.026 Jarque-Bera (JB): 7.438
Skew: -0.326 Prob(JB): 0.0243
Kurtosis: 2.969 Cond. No. 1.39e+05


Warnings:
[1] Standard Errors are heteroscedasticity robust (HC1)
[2] The condition number is large, 1.39e+05. This might indicate that there are
strong multicollinearity or other numerical problems.

Quels sont les retributeurs importants (variables indépendantes) actuellement?

model_hc1.significant_regressors(0.05)
['avginc', 'enrltot', 'expnstu']

Les retours de «str» (ratio élèves-enseignant) et «expnstu» sont particulièrement pertinents pour investir dans les étudiants. Vous pouvez faire un ** test Wald ** pour tester si les deux rétributeurs sont ensemble et significativement différents de 0.

from appelpy.diagnostics import wald_test
wald_stats = wald_test(model_hc1, ['str', 'expnstu'])
print('Wald test :: {}'.format(wald_stats['distribution'] + '({})'.format(wald_stats['nu'])))
print('Test statistic: {:.4f}'.format(wald_stats['test_stat']))
print('Test p-value: {:.4f}'.format(wald_stats['p_value']))
Wald test :: chi2(2)
Test statistic: 4.7352
Test p-value: 0.0937

Sans surprise, l'erreur standard de certaines variables est plus élevée avec l'erreur HC1 qu'avec l'erreur non robuste.

pd.concat([pd.Series(model_nonrobust.results.bse, name='std_error_nonrobust'),
           pd.Series(model_hc1.results.bse, name='std_error_hc1')], axis='columns')
std_error_nonrobust std_error_hc1
const 27.833430 29.364467
avginc 0.185093 0.239715
str 0.892703 0.931541
enrltot 0.000341 0.000278
expnstu 0.002613 0.002794

Observations anormales: effet de levier, valeurs aberrantes et influence

Inspectons les résultats observés.

--Haute influence --Effet de levier élevé --Plus

from appelpy.diagnostics import BadApples

Configurez une instance de BadApples à l'aide d'un objet modèle.

bad_apples = BadApples(model_hc1).fit()

Tracons la valeur de levier par rapport au carré du résidu normalisé.

Les observations dans le quadrant supérieur droit ont un effet de levier et des valeurs résiduelles supérieurs à la moyenne (c'est-à-dire les observations les plus influentes du modèle).

fig, ax = plt.subplots(figsize=(11,7))
bad_apples.plot_leverage_vs_residuals_squared(annotate=True)
plt.show()

output_53_0.png

Influence

La valeur de l'effet de levier est stockée dans l'attribut mesures_leverage.

bad_apples.measures_leverage.sort_values(ascending=False).head()
48     0.113247
34     0.085633
404    0.076762
413    0.065741
159    0.061353
Name: leverage, dtype: float64

Jetons un coup d'œil aux cinq observations les plus exploitées.

bad_apples.show_extreme_observations().loc[[48,34,404,413,159]]
scrtot avginc str enrltot expnstu
48 1261.099976 12.109128 19.017494 27176 5864.366211
34 1252.200012 11.722225 21.194069 25151 5117.039551
404 1387.900024 55.327999 16.262285 1059 6460.657227
413 1398.200012 50.676998 15.407042 687 7217.263184
159 1294.500000 14.298300 20.291372 21338 5123.474121
model_hc1.X_standardized.loc[[48,34,404,413,159]]
avginc str enrltot expnstu
48 -0.443884 -0.329278 6.273077 0.870684
34 -0.497428 0.821246 5.755585 -0.308182
404 5.537230 -1.785664 -0.401163 1.811299
413 4.893572 -2.237740 -0.496228 3.004803
159 -0.140922 0.344087 4.781167 -0.298032

Ces points à fort effet de levier ont des valeurs où au moins une variable indépendante est à au moins 4 écarts-types de la moyenne.

Outlier

L'objet BadApples calcule une heuristique pour déterminer si la valeur d'échelle est "extrême".

Les index extrêmes sont stockés dans des attributs, par exemple les valeurs aberrantes sont stockées dans ʻindices_outliers`.

bad_apples.indices_outliers
[5, 6, 7, 8, 9, 10, 13, 14, 37, 38, 47, 134, 370, 392, 403, 404, 415, 417]

Heuristique des valeurs aberrantes: si la valeur absolue des résidus standardisés ou la valeur absolue des résidus étudiés est supérieure à 2, la valeur observée est une valeur aberrante.

print(f"Proportion of observations as outliers: {len(bad_apples.indices_outliers) / len(df):.4%}")
Proportion of observations as outliers: 4.2857%

En raison de son heuristique, moins d'environ 5% des valeurs observées devraient être considérées comme des valeurs aberrantes.

Influence

Considérez également diverses mesures d'influence telles que la distance de cuisson, les dffits et le dfbeta.

bad_apples.measures_influence.sort_values('cooks_d', ascending=False).head()
dfbeta_const dfbeta_avginc dfbeta_str dfbeta_enrltot dfbeta_expnstu cooks_d dffits_internal dffits
404 0.010742 -0.811324 0.068295 0.061925 0.039761 0.152768 -0.873981 -0.882753
403 0.024082 -0.529623 0.016131 0.031978 0.026944 0.063718 -0.564440 -0.567338
413 0.074297 -0.373064 0.013021 0.033955 -0.099557 0.044116 -0.469661 -0.470876
38 -0.277356 -0.193382 0.217223 -0.136237 0.315817 0.030955 -0.393412 -0.397701
415 -0.157629 0.099707 0.045684 -0.026836 0.249169 0.025414 0.356468 0.357936

emballer

--Chargez l'ensemble de données et prétraitez-le avec Pandas. --Appelpy ** ʻeda**: Inspectez l'ensemble de données du modèle avec des fonctions utiles telles que les moments statistiques. --Appelpy ** modélisation **.Linear_modelcontient des classes telles que OLS et WLS pour l'estimation du modèle. Utilisez une courte recette pour chaque modèle pour accéder aux estimations du modèle. --Appelpy **diagnostics **: vérifie si les estimations du modèle sont valides avec des graphiques de diagnostic, des tests statistiques et des diagnostics tels que BadApples` pour l'analyse d'impact.

Vérifions également d'autres fonctionnalités.

--Régression logistique (sous discrete_model)

Recommended Posts

Apprenez APPELPY en 10 minutes - Bibliothèque d'économie métrique appliquée Python
Apprenez les pandas en 10 minutes