Comment calculer les statistiques "t-test" avec numpy
je cherche à générer des statistiques sur un modèle que j'ai créé en python. J'aimerais générer le t-test dessus, mais je me demandais s'il y avait un moyen facile de le faire avec numpy/scipy. Existe-il des bonnes explications autour?
Par exemple, j'ai trois jeux de données qui ressemble à ceci:
[55.0, 55.0, 47.0, 47.0, 55.0, 55.0, 55.0, 63.0]
Maintenant, je voudrais faire le test-t de student.
3 réponses
Dans un scipy.statistiques le paquet il y a quelques ttest_...
fonctions. Voir l'exemple de ici:
>>> print 't-statistic = %6.3f pvalue = %6.4f' % stats.ttest_1samp(x, m)
t-statistic = 0.391 pvalue = 0.6955
la réponse de van en utilisant scipy est tout à fait correcte et en utilisant le scipy.stats.ttest_*
fonctions est très pratique.
mais je suis venu à cette page à la recherche d'une solution avec pur num PY, comme indiqué dans le titre, pour éviter la dépendance scipy. À cette fin, permettez-moi de vous donner l'exemple suivant: https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.standard_t.html
le problème principal est que numpy n'a pas de distribution cumulative fonctions, d'où ma conclusion est que vous devez vraiment utiliser scipy. Quoi qu'il en soit, utiliser seulement num Py est possible:
à partir de la question originale, je suppose que vous voulez comparer vos ensembles de données et juger avec un test t s'il y a une déviation significative? En outre, que les échantillons sont appariés? (Voir https://en.wikipedia.org/wiki/Student%27s_t-test#Unpaired_and_paired_two-sample_t-tests ) Dans ce cas, vous pouvez calculer la valeur t - et p comme donc:
import numpy as np
sample1 = np.array([55.0, 55.0, 47.0, 47.0, 55.0, 55.0, 55.0, 63.0])
sample2 = np.array([54.0, 56.0, 48.0, 46.0, 56.0, 56.0, 55.0, 62.0])
# paired sample -> the difference has mean 0
difference = sample1 - sample2
# the t-value is easily computed with numpy
t = (np.mean(difference))/(difference.std(ddof=1)/np.sqrt(len(difference)))
# unfortunately, numpy does not have a build in CDF
# here is a ridiculous work-around integrating by sampling
s = np.random.standard_t(len(difference), size=100000)
p = np.sum(s<t) / float(len(s))
# using a two-sided test
print("There is a {} % probability that the paired samples stem from distributions with the same means.".format(2 * min(p, 1 - p) * 100))
Une fois que vous obtenez votre valeur t, vous pouvez vous demander comment l'interpréter comme une probabilité -- Je l'ai fait. Voici une fonction que j'ai écrit pour vous aider.
Il est basé sur les infos que j'ai glanées à partir de http://www.vassarstats.net/rsig.html et http://en.wikipedia.org/wiki/Student%27s_t_distribution.
# Given (possibly random) variables, X and Y, and a correlation direction,
# returns:
# (r, p),
# where r is the Pearson correlation coefficient, and p is the probability
# of getting the observed values if there is actually no correlation in the given
# direction.
#
# direction:
# if positive, p is the probability of getting the observed result when there is no
# positive correlation in the normally distributed full populations sampled by X
# and Y
# if negative, p is the probability of getting the observed result, when there is no
# negative correlation
# if 0, p is the probability of getting your result, if your hypothesis is true that
# there is no correlation in either direction
def probabilityOfResult(X, Y, direction=0):
x = len(X)
if x != len(Y):
raise ValueError("variables not same len: " + str(x) + ", and " + \
str(len(Y)))
if x < 6:
raise ValueError("must have at least 6 samples, but have " + str(x))
(corr, prb_2_tail) = stats.pearsonr(X, Y)
if not direction:
return (corr, prb_2_tail)
prb_1_tail = prb_2_tail / 2
if corr * direction > 0:
return (corr, prb_1_tail)
return (corr, 1 - prb_1_tail)