Si j'ai une liste comme celle-ci:
results=[-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
Je veux calculer la variance de cette liste en Python qui est la moyenne des différences au carré de la moyenne.
Comment puis-je m'y prendre? Accéder aux éléments de la liste pour faire les calculs me déroute pour obtenir les différences carrées.
Vous pouvez utiliser la fonction intégrée de numpy var
:
import numpy as np
results = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
print(np.var(results))
Cela vous donne 28.822364260579157
Si - pour une raison quelconque - vous ne pouvez pas utiliser numpy
et/ou vous ne voulez pas utiliser une fonction intégrée pour cela, vous pouvez également le calculer "à la main" en utilisant par exemple a liste de compréhension :
# calculate mean
m = sum(results) / len(results)
# calculate variance using a list comprehension
var_res = sum((xi - m) ** 2 for xi in results) / len(results)
ce qui vous donne le résultat identique.
Si vous êtes intéressé par l'écart type , vous pouvez utiliser numpy.std :
print(np.std(results))
5.36864640860051
@ Serge Ballesta a très bien expliqué la différence entre la variance n
et n-1
. Dans numpy, vous pouvez facilement définir ce paramètre en utilisant l'option ddof
; sa valeur par défaut est 0
, donc pour le n-1
cas où vous pouvez simplement faire:
np.var(results, ddof=1)
La solution "à la main" est donnée en @ réponse de Serge Ballesta .
Les deux approches donnent 32.024849178421285
.
Vous pouvez également définir le paramètre pour std
:
np.std(results, ddof=1)
5.659050201086865
Eh bien, il existe deux façons de définir la variance. Vous avez la variance n que vous utilisez lorsque vous avez un ensemble complet, et la variance n-1 que vous utilisez lorsque vous avez un échantillon.
La différence entre les 2 est de savoir si la valeur m = sum(xi) / n
est la moyenne réelle ou si c'est juste une approximation de ce que devrait être la moyenne.
Exemple 1: vous voulez connaître la taille moyenne des élèves d'une classe et sa variance: ok, la valeur m = sum(xi) / n
est la moyenne réelle, et les formules données par Cleb sont ok (variance n ).
Exemple2: vous voulez connaître l'heure moyenne à laquelle un bus passe à l'arrêt de bus et sa variance. Vous notez l'heure pendant un mois et obtenez 30 valeurs. Ici, la valeur m = sum(xi) / n
n'est qu'une approximation de la moyenne réelle, et cette approximation sera plus précise avec plus de valeurs. Dans ce cas, la meilleure approximation de la variance réelle est la variance n-1
varRes = sum([(xi - m)**2 for xi in results]) / (len(results) -1)
Ok, cela n'a rien à voir avec Python, mais cela a un impact sur l'analyse statistique, et la question est étiquetée statistiques et variance
Remarque: généralement, les bibliothèques statistiques comme numpy utilisent la variance n pour ce qu’elles appellent var
ou variance
, et le variance n-1 pour la fonction qui donne l'écart type.
Démarrage Python 3.4
, la bibliothèque standard est livrée avec la fonction variance
( exemple de variance ou variance n-1) dans le cadre du module statistics
:
from statistics import variance
# data = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439, 0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
variance(data)
# 32.024849178421285
Le p variance d'opulation (ou variance n) peut être obtenu en utilisant la fonction pvariance
:
from statistics import pvariance
# data = [-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439, 0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
pvariance(data)
# 28.822364260579157
Notez également que si vous connaissez déjà la moyenne de votre liste, les fonctions variance
et pvariance
prennent un deuxième argument (respectivement xbar
et mu
) afin pour éviter de recalculer la moyenne de l'échantillon (qui fait partie du calcul de variance).
Numpy est en effet le moyen le plus élégant et le plus rapide de le faire.
Je pense que la vraie question était de savoir comment accéder aux éléments individuels d'une liste pour faire un tel calcul vous-même, donc ci-dessous un exemple:
results=[-14.82381293, -0.29423447, -13.56067979, -1.6288903, -0.31632439,
0.53459687, -1.34069996, -1.61042692, -4.03220519, -0.24332097]
import numpy as np
print 'numpy variance: ', np.var(results)
# without numpy by hand
# there are two ways of calculating the variance
# - 1. direct as central 2nd order moment (https://en.wikipedia.org/wiki/Moment_(mathematics))divided by the length of the vector
# - 2. "mean of square minus square of mean" (see https://en.wikipedia.org/wiki/Variance)
# calculate mean
n= len(results)
sum=0
for i in range(n):
sum = sum+ results[i]
mean=sum/n
print 'mean: ', mean
# calculate the central moment
sum2=0
for i in range(n):
sum2=sum2+ (results[i]-mean)**2
myvar1=sum2/n
print "my variance1: ", myvar1
# calculate the mean of square minus square of mean
sum3=0
for i in range(n):
sum3=sum3+ results[i]**2
myvar2 = sum3/n - mean**2
print "my variance2: ", myvar2
vous donne:
numpy variance: 28.8223642606
mean: -3.731599805
my variance1: 28.8223642606
my variance2: 28.8223642606
La bonne réponse consiste à utiliser l'un des packages comme NumPy, mais si vous souhaitez lancer le vôtre et que vous voulez le faire de manière incrémentielle, il existe un bon algorithme qui a une plus grande précision. Voir ce lien https://www.johndcook.com/blog/standard_deviation/
J'ai porté mon implémentation Perl sur Python. Veuillez signaler les problèmes dans les commentaires.
Mklast = 0
Mk = 0
Sk = 0
k = 0
for xi in results:
k = k +1
Mk = Mklast + (xi - Mklast) / k
Sk = Sk + (xi - Mklast) * ( xi - Mk)
Mklast = Mk
var = Sk / (k -1)
print var
La réponse est
>>> print var
32.0248491784
import numpy as np
def get_variance(xs):
mean = np.mean(xs)
summed = 0
for x in xs:
summed += (x - mean)**2
return summed / (len(xs) - 1)
print(get_variance([1,2,3,4,5]))
sur 2,5
a = [1,2,3,4,5]
variance = np.var(a, ddof=1)
print(variance)