STATA

Sommaire

Cette section a vocation à présenter certains des outils mobilisés au cours de mes recherches empiriques


Cartographie et intensité

Télécharger l'ensemble du .do file et des données :


L'objectif est de reproduire la carte représentant la répartition des emprunts structurés toxiques Dexia des différentes communes en ajoutant un élément d'intensité basé sur le ratio de surcoût. Cette carte est tirée de l'article "Le fonds de sortie des emprunts toxiques : une alternative au contentieux ?".

Étape 1

Il faut dans un premier temps se munir d'une carte "shapefile". Pour cela, on utilise ici une carte avec les contours des départements [accessible ici]. Une carte sans ces contours est possible. De même qu'il est possible d'obtenir une carte avec les contours des communes (bien plus lourde cependant). On utilise ici la carte avec une simplification à 100m [accessible ici]:

Télécharger le fichier .zip et le décompresser pour conserver uniquement les deux fichiers .dbf et .shp.

Étape 2

On va maintenant transformer la carte "shapefile" en base de donnée de coordonénes .dta. On utilise la commande shp2dta.

Si elle n'est pas intallée, il faut bien entendu commencer par l'installer :

ssc install shp2dta

On transforme ensuite :

shp2dta using departements-20140306-100m, data(d10) coord(c10) replace

  • shp2dta using filename, spécifie le fichier .shp à utiliser

  • database(filename) spécifie le nom de la nouvelle base .dta qui contiendra les données .dbf

  • coordinates(filename) spécifie le nom de la nouvelle base .dta qui contiendra les données .shp

Étape 3

On fusionne la nouvelle base carte avec une autre base comportant elle aussi des coordonnées associées à chaque commune ainsi qu'un certain nombre de variables. Les deux bases se trouvent dans le même dossier (pour simplifier).

use c10, clear

merge using DataDexiaLibe

Puis on crée la variable d'intensité.

gen dsc = .

replace dsc = 0 if Ratio_SurcourtMontant < 10

replace dsc = 1 if Ratio_SurcourtMontant >=10 & Ratio_SurcourtMontant < 20

replace dsc = 2 if Ratio_SurcourtMontant >=20 & Ratio_SurcourtMontant < 40

replace dsc = 3 if Ratio_SurcourtMontant >=40

Étape 4

On utilise des dégradés de couleurs full_palette qui requièrent un package :

ssc install full_palette

On utilise enfin twoway pour faire un graphique. Les coordonnées dans la première base sont _Y et _X. Dans la seconde base ils sont Geo_1 et Geo_0. Bien souvent, si l'on se focalise sur la métropole, il est necessaire de couper en dessous de la latitude 40 :

twoway (area _Y _X if _Y>40, nodropbase cmiss(n) fi(100) fcol(gs14) lcolor(white)) ///

(scatter Geo_1 Geo_0 if Geo_1>40 & dsc == 0 ,nodropbase cmiss(n) mcol(cranberry*0.4)) ///

(scatter Geo_1 Geo_0 if Geo_1>40 & dsc == 1 ,nodropbase cmiss(n) mcol(cranberry*0.7)) ///

(scatter Geo_1 Geo_0 if Geo_1>40 & dsc == 2 ,nodropbase cmiss(n) mcol(cranberry*1.1)) ///

(scatter Geo_1 Geo_0 if Geo_1>40 & dsc == 3 ,nodropbase cmiss(n) mcol(cranberry*1.5)) ///

,legend(order(2 3 4 5) ///

subtitle("Ratio de surcoût :") col(1) position(3) ///

label(2 "< 10%") label(3 "10% – 20%") label(4 "20% – 40%") label(5 "> 40%") ///

region(lcolor(black))) ysc(off) yla(,nogrid) xsc(off) plotregion(color(white)) graphr(color(white) fc(white)) bgcolor(white) xsize(5.5) ysize(4)





Precision-Recall et Receiver Operating Characteristic

Dans certains cas de figure, lorsque l'on souhaite prédire une issue relativement rare (déséquilibre de classe), la courbe Receiver Operating Characteristic (ROC) et la statistique AUROC mesurant l'aire sous cette courbe peuvent conduire à surévaluer la capacité prédictive d'une variable et fausser la comparaison des prédicteurs.

Dans un travail sur la crise Dexia (papier accessible ici), nous avons cherché à déterminer le prédicteur de l'octroi d'une aide du fonds de soutien, évènement rare puisque dans notre échantillon, 120 communes bénéficient d'une aide contre 1422 communes qui n'en bénéficient pas.

Receiver Operating Characteristic (ROC)

La courbe ROC représente le taux de vrais positifs (la sensibilité ou le recall) en fonction du taux de faux positifs (anti-spécificité). L'aire sous cette courbe peut être anormalement élevée lorsque le prédicteur retenu aura une capacité à détecter les vrais positifs au prix de nombreux faux positifs (faible précision), ce qui est un phénomène qui survient d'autant plus que l'échantillon présente une très faible proportion d'issues positives.

Precision-Recall

Une solution à ce problème est de considérer la courbe Precision-Recall qui a l'avantage de considérer la précision du prédicteur au travers de la fraction de vrais positifs parmi les prédictions positives. Cette courbe représente cette mesure de précision en fonction du taux de vrais positifs (recall), ce dernier étant un élément commun avec la courbe ROC.

Pour plus de détails consulter Saito et Rehmsmeier (2015)

Ci-dessous, la structure type de code pour comparer la capacité de deux variables explicatives X1 et X2 à prédire l'occurence de l'èvement Y. Dans la figure ci-dessus, il s'agit de prédire l'occurence de l'octroi d'une aide par le fonds de soutien pour les communes exposées aux emprunts toxiques, avec X1 le ratio de surcoût total et X2 le taux d'endettement. La courbe Precision-Recall confirme que le ratio de surcoût a une meilleure capacité prédictive que le taux d'endettement, comme le suggérait la courbe ROC. Bien que cet élément de robustesse soit important, il souligne aussi que le ratio de surcoût est loin d'offrir une classification parfaite.


* Precision Recall Curve

prtab Y X1 , compare(X2)

* Receiving Operator Curve

logit Y X1 , vce(robust)

predict m1 , xb

logit Y X2 , vce(robust)

predict m2 , xb

roccomp Y m1 m2 , graph summary


2SLS Analogs for weak instruments testing

Cette procédure a été proposée par Bazzi et Clemens (2013) pour transposer les tests du cadre 2SLS à l'estimation en GMM. Ici la procédure est adaptée à l'exemple de la Table 6 dans Too Much Finance or Too Many Weak Instruments? (Fajeau 2021) décomposant l'estimation d'un modèle quadratique autour du crédit au secteur privé.

clear all

set more off

set matsize 3000

cd "/Users/..."

use data

* Création des matrices d'instruments

global z1 growth lgdp_pc privcr22 privcr2 lgovc lopen linfl lschool

forvalues t=2/10 {

forvalues lag=1/`=`t'-1' {

foreach v in $z1 {

qui gen z`t'L`lag'L`v'=L`lag'.`v' if period==`t'

qui gen z`t'L`lag'D`v'=D.L`lag'.`v' if period==`t'

}

}

}

qui recode z* (.=0)

* Pour la matrice d'instruments type collapse

foreach v in $z1 {

foreach l in 1 2 3 4 5 6 7 8 9 {

qui gen L`l'L`v'=L`l'.`v'

qui gen L`l'D`v'=D.L`l'L`v'

}

}

qui recode L* (.=0)

* Column 1 : GMM-SYS

quiet xtabond2 growth lgdp_pc lschool privcr2 privcr22 lgovc lopen linfl pp?, gmm(L.(lgdp_pc lschool privcr2 privcr22 lgovc lopen linfl), lag(. .)) iv(pp?, eq(level)) two robust

gen A=e(sample)

* Column 2 : Diff-2SLS (long mais fonctionne)

ivreg2 d.growth (d.(lgdp_pc privcr2 privcr22 lgovc lopen linfl lschool) = ///

z*L2Llgdp_pc z*L2Lprivcr2 z*L2Lprivcr22 z*L2Llgovc z*L2Llopen z*L2Llinfl z*L2Llschool ///

z*L3Llgdp_pc z*L3Lprivcr2 z*L3Lprivcr22 z*L3Llgovc z*L3Llopen z*L3Llinfl z*L3Llschool ///

z*L4Llgdp_pc z*L4Lprivcr2 z*L4Lprivcr22 z*L4Llgovc z*L4Llopen z*L4Llinfl z*L4Llschool ///

z*L5Llgdp_pc z*L5Lprivcr2 z*L5Lprivcr22 z*L5Llgovc z*L5Llopen z*L5Llinfl z*L5Llschool ///

z*L6Llgdp_pc z*L6Lprivcr2 z*L6Lprivcr22 z*L6Llgovc z*L6Llopen z*L6Llinfl z*L6Llschool ///

z*L7Llgdp_pc z*L7Lprivcr2 z*L7Lprivcr22 z*L7Llgovc z*L7Llopen z*L7Llinfl z*L7Llschool ///

z*L8Llgdp_pc z*L8Lprivcr2 z*L8Lprivcr22 z*L8Llgovc z*L8Llopen z*L8Llinfl z*L8Llschool ///

z*L9Llgdp_pc z*L9Lprivcr2 z*L9Lprivcr22 z*L9Llgovc z*L9Llopen z*L9Llinfl z*L9Llschool )///

pp? if A==1, r small

* On a ici toute la matrice. Le lag ne vas pas plus loin que 9, sur 10 périodes, on a 9 lags si on se positione à la dernière période. Ici on n'intègre pas d'instruments liés aux dummies temporelles car ce ne sont pas les instruments types GMM.

* Column 3 : Diff-2SLS collapsed

ivreg2 d.growth (d.(lgdp_pc privcr2 privcr22 lgovc lopen linfl lschool) = ///

L2Llgdp_pc L2Lprivcr2 L2Lprivcr22 L2Llgovc L2Llopen L2Llinfl L2Llschool ///

L3Llgdp_pc L3Lprivcr2 L3Lprivcr22 L3Llgovc L3Llopen L3Llinfl L3Llschool ///

L4Llgdp_pc L4Lprivcr2 L4Lprivcr22 L4Llgovc L4Llopen L4Llinfl L4Llschool ///

L5Llgdp_pc L5Lprivcr2 L5Lprivcr22 L5Llgovc L5Llopen L5Llinfl L5Llschool ///

L6Llgdp_pc L6Lprivcr2 L6Lprivcr22 L6Llgovc L6Llopen L6Llinfl L6Llschool ///

L7Llgdp_pc L7Lprivcr2 L7Lprivcr22 L7Llgovc L7Llopen L7Llinfl L7Llschool ///

L8Llgdp_pc L8Lprivcr2 L8Lprivcr22 L8Llgovc L8Llopen L8Llinfl L8Llschool ) ///

pp? if A==1, r small

* L2L'variable' est une matrice de type collapsed qui débute au deuxième lag. En pratique, dans la régression xtabond2 on a utilisé l'option gmm(L.variable, lag(. .)) ce qui fait que lag(. .) est identique à lag(1 .). Ainsi on a mécaniquement un départ au deuxième lag alors que gmm(variable, lag(2 .)) ne serait pas traduit identiquement lorsque l'on met l'option collapse qui ne tien plus compte de l'option lag(2 .). Il faut bien ajouter la structure en escalier, on n'a plus la dimension "un moment par période et par profondeur" mais juste un moment par "profondeur"

* Column 4 : Lev-2SLS

ivreg2 growth (lgdp_pc privcr2 privcr22 lgovc lopen linfl lschool = z*L1Dlgdp_pc z*L1Dprivcr2 z*L1Dprivcr22 z*L1Dlgovc z*L1Dlopen z*L1Dlinfl z*L1Dlschool) pp? if A==1,r small

* On prend bien z*L1D : z* va nous donner la forme diagonale, pour chaque période on prends la différence une période avant le L1D nous premet d'avoir pour t=3 la différence entre t=2 et t=1 et ainsi de suite.

* Column 5 : Lev-2SLS Collapsed

ivreg2 growth (lgdp_pc privcr2 privcr22 lgovc lopen linfl lschool = L1Dlgdp_pc L1Dprivcr2 L1Dprivcr22 L1Dlgovc L1Dlopen L1Dlinfl L1Dlschool ) pp? if A==1,r small

* Pour les RELATIVE OLS BIAIS

* a. LOAD STOCK-YOGO CRITICAL VALUE MATRICES

use lambfitSize,clear

mkmat k2-n2_s25, mat(size)

use lambfitBias,clear

mkmat k2-n3_b30, mat(bias)

* b. Remplacer

* e(exexog_ct) : Exogenous instruments

* n : 10 permet d'être dans le cas où on considère 3 variables endogènes (le maximum)

* e(widstat) : KLEINBERGEN

* e(cdf) : CRAGG DONALD F-stat

* SIZE

local widstat = .0024716047346129

local cdf = .0024596031526091

local exexog_ct = 7

local K2 = min(100,`exexog_ct')

local n = 10

local p10KP = 1-nchi2(`K2',`K2'*size[`K2',`n'],`K2'*`widstat')

local p15KP = 1-nchi2(`K2',`K2'*size[`K2',`=`n'+1'],`K2'*`widstat')

local p20KP = 1-nchi2(`K2',`K2'*size[`K2',`=`n'+2'],`K2'*`widstat')

local p25KP = 1-nchi2(`K2',`K2'*size[`K2',`=`n'+3'],`K2'*`widstat')

local p10CD = 1-nchi2(`K2',`K2'*size[`K2',`n'],`K2'*`cdf')

local p15CD = 1-nchi2(`K2',`K2'*size[`K2',`=`n'+1'],`K2'*`cdf')

local p20CD = 1-nchi2(`K2',`K2'*size[`K2',`=`n'+2'],`K2'*`cdf')

local p25CD = 1-nchi2(`K2',`K2'*size[`K2',`=`n'+3'],`K2'*`cdf')

display `p10KP'

display `p15KP'

display `p20KP'

display `p25KP'

display `p10CD'

display `p15CD'

display `p20CD'

display `p25CD'

* BIAS

local widstat = .0024716047346129

local cdf = .0024596031526091

local exexog_ct = 7

local K2 = min(98,`exexog_ct'-2)

local n = 10

local p5KPb = 1-nchi2(`K2',`K2'*bias[`K2',`n'],`K2'*`widstat')

local p10KPb = 1-nchi2(`K2',`K2'*bias[`K2',`=`n'+1'],`K2'*`widstat')

local p20KPb = 1-nchi2(`K2',`K2'*bias[`K2',`=`n'+2'],`K2'*`widstat')

local p30KPb = 1-nchi2(`K2',`K2'*bias[`K2',`=`n'+3'],`K2'*`widstat')

local p5CDb = 1-nchi2(`K2',`K2'*bias[`K2',`n'],`K2'*`cdf')

local p10CDb = 1-nchi2(`K2',`K2'*bias[`K2',`=`n'+1'],`K2'*`cdf')

local p20CDb = 1-nchi2(`K2',`K2'*bias[`K2',`=`n'+2'],`K2'*`cdf')

local p30CDb = 1-nchi2(`K2',`K2'*bias[`K2',`=`n'+3'],`K2'*`cdf')

display `p5KPb'

display `p10KPb'

display `p20KPb'

display `p30KPb'

display `p5CDb'

display `p10CDb'

display `p20CDb'

display `p30CDb'