web-dev-qa-db-fra.com

Test du Chi-Squared en Python

J'ai utilisé le code suivant dans R pour déterminer dans quelle mesure les valeurs observées (20, 20, 0 et 0 par exemple) correspondent aux valeurs/ratios attendus (25% pour chacun des quatre cas, par exemple):

> chisq.test(c(20,20,0,0), p=c(0.25, 0.25, 0.25, 0.25))

    Chi-squared test for given probabilities

data:  c(20, 20, 0, 0)

X-squared = 40, df = 3, p-value = 1.066e-08

Comment puis-je répliquer cela en Python? J'ai essayé d'utiliser la fonction chisquare de scipy mais les résultats que j'ai obtenus étaient très différents; Je ne sais pas si c'est même la bonne fonction à utiliser. J'ai cherché dans la documentation scipy, mais c'est assez intimidant car il s'étend sur plus de 1000 pages; la documentation numpy est presque 50% de plus que cela.

26
SabreWolfy

scipy.stats.chisquare attend les fréquences absolues observées et attendues, pas les ratios. Vous pouvez obtenir ce que vous voulez avec

>>> observed = np.array([20., 20., 0., 0.])
>>> expected = np.array([.25, .25, .25, .25]) * np.sum(observed)
>>> chisquare(observed, expected)
(40.0, 1.065509033425585e-08)

Bien que dans le cas où les valeurs attendues soient uniformément réparties sur les classes, vous pouvez laisser de côté le calcul des valeurs attendues:

>>> chisquare(observed)
(40.0, 1.065509033425585e-08)

La première valeur renvoyée est la statistique χ², la seconde la valeur p - du test.

35
Fred Foo

Je voulais simplement souligner que, bien que la réponse semble être syntaxiquement correcte, vous ne devriez pas utiliser une distribution du chi carré avec votre exemple, car vous avez observé des fréquences trop petites pour un test du chi carré précis.

"Ce test n'est pas valide lorsque les fréquences observées ou attendues dans chaque catégorie sont trop petites. Une règle typique est que toutes les fréquences observées et attendues doivent être d'au moins 5." voir: http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.chisquare.html#scipy.stats.chisquare

7
emaxwell

Une alternative serait d'appeler votre code R à partir de python. Tu peux le faire:

  • en exécutant un script R comme outil de ligne de commande. Voir ce lien pour plus d'informations sur l'exécution de scripts R à partir de la ligne de commande à l'aide de Rscript. Depuis python vous pouvez ensuite exécuter un script R en exécutant un appel système en utilisant subprocess ou os.system. Tout échange de données se fait via du texte ou des fichiers binaires. J'aime cette approche car elle est très simple et il est facile de déboguer le script R séparément du code python. L'inconvénient est que toutes les données passent par le disque dur, ce qui pourrait s'avérer être très lent.
  • en utilisant rpy , ou rpy2 pour exécuter le code R directement à partir de python. De cette façon, l'intégration est plus étroite, mais ce lien présente également ses propres petites bizarreries. Par exemple, d'après mon expérience, le débogage du code R appelé via rpy est un peu plus difficile à déboguer.
2
Paul Hiemstra