Variables qualitatives et indépendance

In [1]:
%matplotlib nbagg

import matplotlib
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
/Users/tabea/anaconda/lib/python2.7/site-packages/IPython/kernel/__init__.py:13: ShimWarning: The `IPython.kernel` package has been deprecated. You should import from ipykernel or jupyter_client instead.
  "You should import from ipykernel or jupyter_client instead.", ShimWarning)

Dans ce notebook, nous nous intéressons aux variables qualitatives. Prenons comme exemple le tableau de données suivant, qui contient la répartition des étudiants de ce cours aux deux groupes de TP. Nous nous intéressons à la question si la répartition des filles et garçons au deux groupes de TP est équitable, autrement dit, si les étudiants ont choisi leur groupe de TP indépendamment de leur sexe.

Importons d'abord les données :

In [2]:
etu = pd.read_csv('http://www.proba.jussieu.fr/pageperso/rebafka/listeetudiants.csv',sep=' ',index_col=0)
etu.head()
Out[2]:
Sexe TP
3003120 M 1
3501137 M 2
3102083 F 1
3365501 M 2
3368853 M 2
In [3]:
etu.dtypes
Out[3]:
Sexe    object
TP       int64
dtype: object

Vérifions les modalités possibles des deux variables :

In [4]:
etu['Sexe'].unique()
Out[4]:
array(['M', 'F'], dtype=object)
In [5]:
etu['TP'].unique()
Out[5]:
array([1, 2])

Calcul des effectifs

La fonction value_counts d'une Series calcule les effectifs par modalité de la variable :

In [6]:
etu['Sexe'].value_counts()
Out[6]:
F    18
M    17
Name: Sexe, dtype: int64
In [7]:
etu['TP'].value_counts()
Out[7]:
1    18
2    17
Name: TP, dtype: int64

Remarquons que le type de l'objet renvoyé par value_counts() est aussi une Series :

In [8]:
type(etu['TP'].value_counts())
Out[8]:
pandas.core.series.Series

Afin de savoir si la répartition des filles/garçons sur les deux groupes est équitable, on calcule le nombre de filles/garçons par groupe de TP :

In [9]:
nF_TP1 = ((etu['Sexe']=='F')&(etu['TP']==1)).sum()
print 'nF_TP1:', nF_TP1
nF_TP2 = ((etu['Sexe']=='F')&(etu['TP']==2)).sum()
print 'nF_TP2:', nF_TP2
nF_TP1: 13
nF_TP2: 5
In [10]:
nH_TP1 = ((etu['Sexe']=='M')&(etu['TP']==1)).sum()
print 'nH_TP1:', nH_TP1
nH_TP2 = ((etu['Sexe']=='M')&(etu['TP']==2)).sum()
print 'nH_TP2:', nH_TP2
nH_TP1: 5
nH_TP2: 12

Diagramme en bâtons

On peut représenter les effectifs de filles/garçons par groupe de TP graphiquement par un diagramme en bâtons avec des couleurs différentes pour les filles/garçons :

In [11]:
ind = np.arange(2) # les coordonnées des abscisses x des bâtons
width = 0.35       # largeur des bâtons 

filles = [nF_TP1,nF_TP2]
garcons = [nH_TP1,nH_TP2]

plt.figure()
p1 = plt.bar(ind, filles, width, color='r')
p2 = plt.bar(ind, garcons, width, color='b', bottom=filles)

plt.title('Nombres de filles/garcons par groupe de TP')
plt.xticks(ind + width/2., ('TP 1', 'TP 2'))
plt.legend((p1[0], p2[0]), ('Filles', 'Garcons'),loc=0)
Out[11]:
<matplotlib.legend.Legend at 0x107786250>

On observe sur le graphique, que les filles ont clairement préféré s'inscrire au groupe TP 1, alors que les garçons ont manifesté une préférence pour le groupe TP 2. On conclut que les variables Sexe et TP ne sont pas indépendantes.

Statistique de $\chi^2$

Une autre façon pour tester l'indépendance de deux variables qualitatives repose sur la statistique de $\chi^2$ définie par $$\chi^2(X)= \frac1n \sum_{i=1}^{N_1}\sum_{j=1}^{N_2}\frac{(nn_i^j-n_in^j)^2}{n_in^j}$$ où $N_1$ et $N_2$ représentent le nombre de modalités de la première et deuxième variable respectivement, $n_i, n^j$ et $n_i^j$ sont les effectifs de différentes variables et différentes modalités (voir le cours pour les détails) et $n$ est le nombre total d'observations.

Calculons alors la statistique de $\chi^2$ dans notre exemple :

In [12]:
# nb d'etudiants dans le groupe TP1 (i=1) et TP2 (i=2)
n_1 = (etu['TP']==1).sum()
n_2 = (etu['TP']==2).sum()

# nb total d'etudiants
n = n_1+n_2

# nb total de filles (j=1) et de garcons (j=2) 
m_1 = (etu['Sexe']=='F').sum()
m_2 = (etu['Sexe']=='M').sum()

stat_chi2 = 0
# i=1, j=1 :
stat_chi2 += ((n*nF_TP1-n_1*m_1)**2)/float(n_1*m_1)
# i=1, j=2 :
stat_chi2 += ((n*nH_TP1-n_1*m_2)**2)/float(n_1*m_2)
# i=2, j=1 :
stat_chi2 += ((n*nF_TP2-n_2*m_1)**2)/float(n_2*m_1)
# i=2, j=2 :
stat_chi2 += ((n*nH_TP2-n_2*m_2)**2)/float(n_2*m_2)

stat_chi2 = stat_chi2/n

print 'stat_chi2', stat_chi2
stat_chi2 6.41457345465

Interprétation de la valeur de la statistique de $\chi^2$

En général, une petite valeur de $\chi^2$ est en faveur de l'hypothèse de l'indépendance des deux variables, alors qu'une grande valeur de $\chi^2$ implique que les deux variables ne sont pas indépendantes.

Si la valeur est suffisamment "grande" ou "petite" pour pouvoir conclure dépend du nombre de modalités des deux variables.

Plus précisément, on peut calculer ce qu'on appelle le degré de liberté $d$ de la statistique de $\chi^2$ défini par $$d= (N_1-1)(N_2-1)$$ où $N_1$ et $N_2$ sont le nombre de modalités de la première et deuxième variable, respectivement.

Enfin, dans la pratique, il est courant de conclure que les deux variables ne sont pas indépendantes si la p-value, que l'on obtient par les instructions suivantes, est inférieure à 0.05 :

In [13]:
from scipy.stats import chi2

N1 = len(etu['TP'].unique()) # nb de modalites de la premiere variable
N2 = len(etu['Sexe'].unique()) # nb de modalites de la 2e variable
d = (N1-1)*(N2-1)  # degré de liberté 
p_value = 1-chi2.cdf(stat_chi2,d)
print 'p_value', p_value
p_value 0.0113187513043

Exercice

Nous allons étudier des données sur (une partie) des passengers du RMS Titanic, qui a fait naufrage en avril 1912. Nous disponsons, entre autre, des informations suivantes sur les passengers : le nom, le sexe, l'âge, le port d'embarcation, le prix du billet, la classe et, bien sûr, l'inforamtion si le passenger a survécu ou pas au naufrage.

  1. Importer le tableau des données disponible à l'adresse http://www.proba.jussieu.fr/pageperso/rebafka/titanic.csv

    • Familiarisez-vous avec les données (taille du tableau, type des variables etc.).
    • Vérifier s'il y a des NaN (mais ne supprimer pas les lignes correspondantes s'il y en a).
    • Créer un tableau qui ne contient que les variables Survived, Pclass, Sex, Age et Embarked.
    • Tracer l'histogramme de la répartition de l'âge des passengers.
    • Pour cet exercice, au lieu de travailler avec l'âge exacte des passengers, on préfère regrouper les passenger par tranches d'âge : ajouter une colonne nommée Tranche d'age au tableau qui indique l'âge par tranche de dix ans. Par exemple, on mettra 0 pour des enfants de moins de 10, 10 pour les personnes de 10 à 19 etc.
  2. Nous nous intéressons particulièrement à la variable Survived et à la question si cette variable est indépendante des autres variables.

    • Pour commencer, calculer la proportion de passengers ayant survécu.
    • Ensuite, calculer le nombre et la proportion des femmes et puis des hommes qui ont survécu.
    • Représenter ces valeurs par un diagramme en bâtons.
    • Est-ce que les variables Survived et Sex semblent être indépendantes ?
    • Ecrire une fonction qui prend en argument une variable var du tableau de données. Cette fonction trace le diagramme en bâtons représentant le nombre de survivants/morts par groupe donné par la variable var. (Autrement dit, si var est la variable Sex, on obtient le même diagramme qu'à la question précédente.)
    • Appliquer cette fonction aux variables Pclass, Tranche d'age et Embarked et interpréter les graphiques.
  3. Calculer la statisique de $\chi^2$ et la p-value correspondante pour tester l'indépendance des variables Survived et Sex. Interpréter le résultat.

    • Ecrire une fontion qui prend en argument une variable var du tableau de données. Cette fonction calcule la statisique de $\chi^2$ et la p-value correspondante pour tester l'indépendance des variables Survived et var.
    • Appliquer cette fonction aux variables Pclass, Tranche d'age et Embarked et interpréter les résultats.
In [ ]: