Réaliser un test d’indépendance Chi2 en Python avec scipy.stats

Ici, je vais montrer comment réaliser un test du Chi2 avec deux variables qualitatives grâce à scipy.stats.chi2_contingency

Analalyse exploratoire

En introduction, j’aimerais vous renvoyer vers l’excellent cours de Nicolas Rangeon qui explique les étapes suivantes :

A partir de deux variables qualitatives, comment :

  1. Construire un tableau de contingence (matrice des valeurs observées)
  2. Construire la matrice des fréquences attendues grâce aux sommes marginales
  3. Construire la matrice des écarts au carré normalisés
  4. Transformer cette dernière matrice en heatmap grâce à seaborn

Il s’agit donc d’une analyse exploratoire permettant de :

  1. Comprendre comment est calculée la statistique khi-2
  2. Mettre en avant les fortes corrélations pour certaines valeurs de nos deux variables.

Test statistique

Bien ! Passons désormais au test d’indépendance pour savoir si nos deux variables sont corrélées ou non. Avant cela, quelques remarques sur la première partie :

La somme totale des valeurs de la matrice de la troisième étape suit une loi du khi-2 à k degrés de liberté. D’après la documentation de SciPy, voici comment est calculé le nombre k :

1
k = observed.size - sum(observed.shape) + observed.ndim - 1

Où observed est le tableau de contingence (matrice de la première étape).

Ici, scipy va (presque) tout faire pour nous. Nous allons nous contenter de réaliser l’étape n°1 de la première partie, à savoir la construction du tableau de contingence. Une fois cette matrice obtenue, scipy va faire le travail.

Les données

Je me contente de reprendre l’exemple utilisé par Nicolas Rangeon dans le cours linké dans la première partie. Il s’agit d’une liste d’individus, pour lesquels on connait deux informations :

Dans quel bar ils ont consommé (nom du bar)
Quelle boisson ont-ils consommé dans ce bar (Café, Thé ou autre).

Voici le code que j’ai écrit pour générer le jeu de données :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
X = ["Chez Luc"]*10
X.extend(["Au café Dembas"]*20)
X.extend(["Au café Ducoing"]*40)
X.extend(["Chez Sarah"]*30)
 
Y = ["Café"]*1
Y.extend(["Thé"]*9)
Y.extend(["Autre"]*0)
 
Y.extend(["Café"]*9)
Y.extend(["Thé"]*6)
Y.extend(["Autre"]*5)
 
Y.extend(["Café"]*20)
Y.extend(["Thé"]*10)
Y.extend(["Autre"]*10)
 
Y.extend(["Café"]*20)
Y.extend(["Thé"]*5)
Y.extend(["Autre"]*5)
 
data = {
    'bar':X,
    'boisson':Y
}
df = pd.DataFrame(data)

Voici le .head() obtenu :

L’idée est simplement d’avoir deux listes de valeurs qualitatives. Chaque ligne doit correspondre à un couple de valeurs.

Générer le tableau de contingence

Ici, on reprend la méthode utilisée dans l’analyse exploratoire (première partie), à savoir :

1
2
3
X = "bar"
Y = "boisson"
cont = df[[X, Y]].pivot_table(index=X, columns=Y, aggfunc=len).fillna(0).copy().astype(int)

En fait c’est très simple, on utilise la méthode pivot_table pour obtenir notre tableau de contingence. J’en profite au passage pour remplacer les valeurs nulles par des zéro, je crée une copie du dataframe original et je m’assure de tout convertir en int.

Et c’est tout ce qu’on a à faire ! Dans la première partie, à ce stade on calcule les sommes marginales grâce à la méthode value_counts(), mais ici pas besoin. Notre matrice des valeurs observées est prête, on a plus qu’à la soumettre à scipy.stats.chi2_contingency. Voici à quoi elle resemble dans notre cas :

Calcul de la p-value

En une ligne, le tour est joué :

1
st_chi2, st_p, st_dof, st_exp = st.chi2_contingency(cont)

Voici les valeurs récupérées :

1
2
3
4
5
6
7
8
# Statistique khi2, calculée à la main dans la première partie
st_chi2 = 21.99
 
# Nombe de degrés de liberté
st_dof = 6
 
# Pvalue : l'unique valeur nécessaire pour prendre notre décision
st_p = 0.00121

On récupère également dans st_exp le tableau des fréquences attendues, que l’on calcule manuellement dans la première partie.

Ce qui nous intéresse ici, c’est la variable st_p, qui contient la pvalue. Celle-ci est calculée par scipy de la manière suivante :

  1. Calcul de la stat khi2
  2. Calcul du nombre de degrés de liberté k
  3. Calcul de la loi à densité suivie par une loi khi2 à k degrés de liberté
  4. Confrontation de la stat khi2 calculée avec la loi à densité obtenue

L’hypothèse nulle est que les variables sont indépendantes. La p-valeur nous indique quelle probabilité (matérialisée par l’aire sous la courbe de la loi à densité) représente les valeurs encore plus éloignées que celle obtenue.

Test au seuil de 1%

Rejetons l’hypothèse nulle au seuil de 1%, donc pour une pvaleur inférieure à 0.01.

Dans notre cas, la pvaleur obtenue par notre échantillon est de 0.00121, ce qui est en dessous du seuil fixé. On peut donc rejeter l’hypothèse nulle. Les variables « nom du bar » et « boisson consommée » ne sont pas indépendantes. Ceci confirme ce qu’on aurait pu intuitivement deviner dans notre cas, juste avec l’analyse exploratoire.

Voici un notebook sur lequel vous trouverez l’ensemble du code :Test-du-khi2

2 réponses sur “Réaliser un test d’indépendance Chi2 en Python avec scipy.stats”

  1. Super clair !
    Excellent tuto pour débutant. Bravo Nicolas !
    Je le poste sur linkedin (mes la plupart de mes contacts sont anglophones)

Répondre à generic cialis Annuler la réponse

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *