top of page

Discrimination salariale femme-homme : comment vraiment la mesurer ?


Image faite à l'aide de Dall-E 2



Depuis 1995, les inégalités de temps de travail et de salaire ont diminué de 4 et 7 points respectivement. Les écarts salariaux sont principalement dus à la répartition genrée des professions, les femmes ayant moins accès aux postes les plus rémunérateurs. À poste comparable, l'écart de salaire est réduit à environ 4% (source : INSEE).


Très regardés par les équipes Comp & Ben, les écarts de salaire restent mal quantifiés car les techniques traditionnelles issues du contrôle de gestion (écart à la moyenne, médianes, etc...) et de reporting RH ne peuvent analyser en profondeur le phénomène.


Dans ce post, je montre pourquoi et comment utiliser la méthode Blinder-Oaxaca (utilisée par l'INSEE et la DARES) avec un cas simple en Python.



Sommaire :


 

1. Un problème de choix


Outre le fait que ce soit un sujet d'actualité. Il faut bien comprendre que, pour nous autres gestionnaires RH, l'utilisation des techniques classiques pour ce cas précis est dommageable. Non seulement pour les femmes, mais aussi pour l'entreprise. J'explique :


L'analyse purement graphique et comptable des écarts de salaire est bordélique à souhait. On commence par prendre les salaires des hommes et des femmes, on fait notre première moyenne. Puis, on subdivise nos deux populations par catégories socio-professionnelles ou hiérarchique et on refait un moyenne. Puis, on re-subdivise ces catégories par départements et ainsi de suite. À ce moment là, on arrive plus à savoir qui est discriminé et qui ne l'est pas, la granularité est trop importante. Le salaire des femmes apparait (généralement) inférieur aux hommes dans chaque table, certes, mais que décider ? Quel montant allouer ? À qui ? Quelle variable influence le plus cette discrimination ? Sur quelle base vais-je justifier que les femmes du département X doivent avoir une augmentation par rapport à celle du département Y ?


Vous voyez de quoi je parle, j'en suis sûr.


En général, l'équipe en charge du problème va se fixer un cadre, une méthodologie, qu'elle réutilisera à chaque fois. Par exemple, elle va subdiviser la population en homme et femme et faire une nouvelle table en regardant l'ancienneté et/ou la place dans la hiérarchie, puis, comparer entre les deux groupes. Néanmoins, cela pose deux problèmes :

  1. En conservant la même méthodologie, l'équipe n'arrivera à réduire l'écart que partiellement car le salaire est composé d'une multitude de facteur qu'il convient d'analyser dans son ensemble

  2. Certaines femmes vont se retrouver avec un niveau de salaire supérieur à celui d'autres femmes alors qu'elles ne le méritent peut-être pas (et oui, la/les variable(s) choisi(es) ont peut être moins d'influence(s) sur le salaire que ce que l'on pense)


Mais alors, comment faire ? C'est là que l'analytique RH entre en scène. Seul l'utilisation de techniques plus avancées (mais pas trop quand même) va permettre de quantifier et synthétiser l'ensemble des variables et permettre de poser un chiffre sur notre problème.



2. La méthode Blinder-Oaxaca


La méthode Blinder-Oaxaca, également connue sous le nom de décomposition Blinder-Oaxaca, est une technique économétrique utilisée pour analyser et décomposer les différences de moyennes observées entre deux groupes. Elle est couramment utilisée pour étudier les écarts de salaires entre différentes catégories de travailleurs, par exemple entre les hommes et les femmes ou entre différents groupes ethniques. Cette méthode a été développée par Alan S. Blinder et Manuelita Ureta en 1973, puis étendue par Ronald Oaxaca en 1973.

La décomposition Blinder-Oaxaca repose sur l'idée que les écarts de salaires entre deux groupes peuvent être décomposés en deux parties :

  1. La partie "expliquée" : Cette partie est due aux différences observables entre les deux groupes, telles que l'éducation, l'expérience professionnelle, l'âge ou d'autres caractéristiques pertinentes. En d'autres termes, elle correspond à la portion de l'écart salarial qui peut être attribuée à des facteurs mesurables.

  2. La partie "inexpliquée" : Cette partie correspond à la portion de l'écart salarial qui ne peut pas être expliquée par les différences observables entre les deux groupes. Elle est souvent interprétée comme une mesure de discrimination, même si d'autres facteurs non observés pourraient également être à l'origine de cette partie inexpliquée.

La méthode Blinder-Oaxaca consiste à estimer des équations de salaires séparées pour chacun des deux groupes à l'aide de régressions linéaires. Ensuite, les différences de salaires sont décomposées en parties expliquées et inexpliquées en utilisant les coefficients estimés de ces régressions. Les chercheurs peuvent alors analyser les résultats pour mieux comprendre les raisons des écarts salariaux et, éventuellement, formuler des politiques pour les réduire.


Attention tout de même, nulle méthode n'est parfaite. Le modèle peut sur ou sous estimé la discrimination à cause de variables omises. Aussi, elle ne prend pas en compte la pré-discrimination, c'est à dire l'écart de salaire qui c'est créé avant l'embauche. La méthode est donc plus fiable que des moyennes classiques mais nécessite (et nécessitera) toujours la un oeil humain.



3. Le calcul


Vous l'avez lu, cette méthode utilise la régression linéaire.


Cas simple avec une variable. On estime deux equations de salaire :



Avec W, le salaire et S, l'ancienneté. Les indices m et f pour hommes et femmes respectivement. On calcul maintenant la moyenne des variables indépendantes (ici S est notre seul variable) pour chaque groupe d'individus. On les notes :



On calcul le salaire moyen de chaque groupe en utilisant la valeur moyenne de l'ancienneté dans l'équation :



On peut maintenant décomposer le salaire en deux parties. La part expliquée :


La part inexpliquée (discrimination potentiel) :


And there you have it ! Plutôt simple et bougrement efficace. Voyons ce que ça donne avec une exemple d'application en Python.



4. Application sur Python


import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import statsmodels.api as sm


# On créer un jeu de données simple
data = {'sexe': ['F', 'F', 'F', 'F', 'F', 'M', 'M', 'M', 'M', 'M'],
        'wages': [52000, 58000, 56000, 53000, 50000, 60000, 62000, 65000, 58000, 55000],
        'seniority': [5, 6, 6, 5, 4, 6, 7, 9, 7, 5]}

df = pd.DataFrame(data)

# Visualisation
sns.scatterplot(data=df, x='seniority', y='wages', hue='sexe', style="sexe")

# Ajoute les titres et les libellés d'axes
plt.xlabel('Seniority')
plt.ylabel('Wages')
plt.title('Scatterplot of Seniority vs Wages with Sexe as Hue')

# Display
plt.show()

# Séparation du jeu selon la variable 'sexe'
df_male = df[df['sexe'] == 'M']
df_female = df[df['sexe'] == 'F']

# Effectue la régression sur chaque dataframes en utilisant statsmodels
X_male = sm.add_constant(df_male['seniority'])
Y_male = df_male['wages']
model_male = sm.OLS(Y_male, X_male).fit()

X_female = sm.add_constant(df_female['seniority'])
Y_female = df_female['wages']
model_female = sm.OLS(Y_female, X_female).fit()

# Affiche les résultats
print("Male linear regression summary:")
print(model_male.summary())
print("\nFemale linear regression summary:")
print(model_female.summary())

On se retrouve avec deux tables de régression (je n'affiche que celle des hommes pour l'exemple) :

Male linear regression summary:
                       OLS Regression Results                            
===================================================================
Dep. Variable:       wages   R-squared:                       0.784
Model:                 OLS   Adj. R-squared:                  0.712
Method:      Least Squares   F-statistic:                     10.87
Date:     Tue, 11 Apr 2023   Prob (F-statistic):             0.0458
Time:             13:10:31   Log-Likelihood:                -43.933
No. Observations:        5   AIC:                             91.87
Df Residuals:            3   BIC:                             91.09
Df Model:                1                                         
Covariance Type: nonrobust                                         
===================================================================
               coef  std err      t    P>|t|      [0.025     0.975]
-------------------------------------------------------------------
const     4.455e+04  4775.97   9.33    0.003    2.93e+04   5.97e+04
seniority   2272.73   689.35    3.3    0.046      78.901   4466.554
===================================================================
Omnibus:               nan   Durbin-Watson:                   0.867
Prob(Omnibus):         nan   Jarque-Bera (JB):                0.422
Skew:               -0.294   Prob(JB):                        0.810
Kurtosis:            1.703   Cond. No.                         36.9
===================================================================

Bon, si vous n'avez jamais vu de table de régression, vous ne saurez pas du tout où regarder. Les informations importantes pour notre cas (indiqués en vert) sont :

  • Le R-squared / R-squared Ajusted : indique la force de notre modèle

  • La colonne "coef" pour les variables "const" et "seniority" : permet de faire la modélisation

PS : il y d'autres choses à regarder normalement (comme la statistique f ou les p-valeurs). Ce n'est pas bloquant, mais on restera dans la simplicité pour l'exemple


# Extraction des paramètres de chaque modèle
params_male = round(model_male.params, 1)
params_female = round(model_female.params, 1)

# Créer un dataframe pour chaque sexe
params_df = pd.DataFrame({'M': params_male, 'F': params_female})

print(params_df)
                 M        F
const      44545.5  34857.1
seniority   2272.7   3642.9

# Je vous l'a fait très descriptive pour bien que vous voyez mais un praticien irait beaucoup plus vite :
# Dans la pratique on ne se cassera pas la tête à sauvegarder chaque variable, on procèdera directement au calcul


# On va chercher la moyenne de la variable "seniority pour les deux groupes"
S_mean_m = df_male["seniority"].mean()
S_mean_f = df_female["seniority"].mean()


# on récupère les paramètres (coefficients)
a_m = params_male[0]
a_f = params_female[0]

b_m = params_male[1]
b_f = params_female[1]


# On modélise le salaire moyen du modèle en insérant la moyenne de la variable "seniority" de chaque groupe
# dans leur équation respective
W_mean_m = a_m + (b_m * S_mean_m)
W_mean_f = a_f + (b_f * S_mean_f)

print("le salaire moyen du modèle des hommes est: ", W_mean_m)
print("le salaire moyen du modèle des femmes est: ", W_mean_f)
le salaire moyen du modèle des hommes est:  59999.86
le salaire moyen du modèle des femmes est:  53800.18
# La part expliquée :
Structural_effect = b_m*(S_mean_m - S_mean_f)
print("La part expliquée est de:", round(Structural_effect,2))

# La part inexpliquée :
potential_discr = (a_m - a_f)+(b_m - b_f)*S_mean_f
print("La part inexpliqué est de:", round(potential_discr,2))
La part expliquée est de: 3636.32
La part inexpliqué est de: 2563.36


# On peut vérifier que l'équation est juste en faisant la différence des salaires moyen du modèle 
# et en la comparant à la somme des deux parties de la décomposition

diff = W_mean_m - W_mean_f
print(diff)

mean_wage_spread = potential_discr + Structural_effect
print(round(mean_wage_spread,2))
6199.68
6199.68


# On peut rapporter chacune des deux parties à la somme de l'écart moyen pour trouver le % de discrimination
percent_struct = (Structural_effect/mean_wage_spread) * 100
print(f"La part expliqué est de: {round(percent_struct,1)}%")

percent_discr = (potential_discr/mean_wage_spread) * 100
print(f"La part inexpliqué est de: {round(percent_discr,1)}%")
La part expliqué est de: 58.7%
La part inexpliqué est de: 41.3%

Voilà ! L'écart de salaire peut être expliqué à 58.7% par le fait que les hommes (dans le jeu de données) ont plus d'ancienneté. En revanche 41.3% de cette écart peut être dû à une discrimination potentielle.


Toujours garder à l'esprit que le salaire est influencé par énormément de variable dans le monde réelle. Vous vous devez d'être le plus exhaustif et extrêmement méticuleux pour ce genre d'analyse. Aussi, renseignez vous sur le sujet. Les critères de discriminations sont définis par loi (cliquer ici pour les connaitre). Il existe une autre branche qui examine la probabilité d'accéder à l'emploi selon ces mêmes critères (cf. la discrimination à l'embauche).



Votre serviteur,

Thomas

Comments


bottom of page