web-dev-qa-db-fra.com

matrice de covariance numpy

Supposons que j'ai deux vecteurs de longueur 25 et que je veuille calculer leur matrice de covariance. J'essaie de faire cela avec numpy.cov, mais je me retrouve toujours avec une matrice 2x2.

>>> import numpy as np
>>> x=np.random.normal(size=25)
>>> y=np.random.normal(size=25)
>>> np.cov(x,y)
array([[ 0.77568388,  0.15568432],
       [ 0.15568432,  0.73839014]])

L'utilisation de l'indicateur rowvar n'aide pas non plus - j'obtiens exactement le même résultat.

>>> np.cov(x,y,rowvar=0)
array([[ 0.77568388,  0.15568432],
       [ 0.15568432,  0.73839014]])

Comment obtenir la matrice de covariance 25x25?

19
user13321

Vous avez deux vecteurs, pas 25. L'ordinateur sur lequel je suis n'a pas python donc je ne peux pas tester cela, mais essayez:

z = Zip(x,y)
np.cov(z)

Bien sûr ... vraiment ce que vous voulez ressemble plus à:

n=100 # number of points in each vector
num_vects=25
vals=[]
for _ in range(num_vects):
    vals.append(np.random.normal(size=n))
np.cov(vals)

Cela prend la covariance (je pense/espère) de num_vects 1x n vecteurs

11
David Marx

Essaye ça:

import numpy as np
x=np.random.normal(size=25)
y=np.random.normal(size=25)
z = np.vstack((x, y))
c = np.cov(z.T)
12
Sylou

Lire la documentation comme,

>> np.cov.__doc__ 

ou en regardant Numpy Covariance , Numpy traite chaque ligne de tableau comme une variable distincte, vous avez donc deux variables et donc vous obtenez une matrice de covariance 2 x 2.

Je pense que le post précédent a la bonne solution. J'ai l'explication :-)

3
Arcturus

Tu devrais changer

np.cov(x,y, rowvar=0)

sur

np.cov((x,y), rowvar=0)
2
foo bar

Ce que vous avez obtenu (2 par 2) est plus utile que 25 * 25. La covariance de X et Y est une entrée hors diagonale dans la cov_matrix symétrique.

Si vous insistez sur (25 par 25) que je pense inutile, alors pourquoi ne pas écrire la définition?

x=np.random.normal(size=25).reshape(25,1) # to make it 2d array.
y=np.random.normal(size=25).reshape(25,1)

cov =  np.matmul(x-np.mean(x), (y-np.mean(y)).T) / len(x)
1
Aerin

Matrice de covariance à partir d'échantillons vecteurs

Pour clarifier la petite confusion concernant ce qu'est une matrice de covariance définie à l'aide de deux vecteurs à N dimensions, il y a deux possibilités.

La question que vous devez vous poser est de savoir si vous considérez:

  • chaque vecteur sous forme de N réalisations/échantillons d'une seule variable (par exemple deux vecteurs tridimensionnels [X1,X2,X3] et [Y1,Y2,Y3], où vous avez 3 réalisations pour les variables X et Y respectivement)
  • chaque vecteur comme 1 réalisation pour N variables (par exemple deux vecteurs tridimensionnels [X1,Y1,Z1] et [X2,Y2,Z2], où vous avez 1 réalisation pour les variables X, Y et Z par vecteur)

Puisqu'une matrice de covariance est définie intuitivement comme une variance basée sur deux variables différentes:

  • dans le premier cas, vous avez 2 variables, N exemples de valeurs pour chacune, donc vous vous retrouvez avec une matrice 2x2 où les covariances sont calculées grâce à N échantillons par variable
  • dans le second cas, vous avez N variables, 2 échantillons pour chacune, donc vous vous retrouvez avec une matrice NxN

À propos de la vraie question, en utilisant numpy

si vous considérez que vous avez 25 variables par vecteur (a pris 3 au lieu de 25 pour simplifier l'exemple de code), donc une réalisation pour plusieurs variables dans un vecteur, utilisez rowvar=0

# [X1,Y1,Z1]
X_realization1 = [1,2,3]

# [X2,Y2,Z2]
X_realization2 = [2,1,8]

numpy.cov([X,Y],rowvar=0) # rowvar false, each column is a variable

Le code renvoie, en considérant 3 variables:

array([[ 0.5, -0.5,  2.5],
       [-0.5,  0.5, -2.5],
       [ 2.5, -2.5, 12.5]])

sinon, si vous considérez qu'un vecteur représente 25 échantillons pour une variable, utilisez rowvar=1 (paramètre par défaut de numpy)

# [X1,X2,X3]
X = [1,2,3]

# [Y1,Y2,Y3]
Y = [2,1,8]

numpy.cov([X,Y],rowvar=1) # rowvar true (default), each row is a variable

Le code renvoie, en considérant 2 variables:

array([[ 1.        ,  3.        ],
       [ 3.        , 14.33333333]])
1
Blupon

Je suppose que ce que vous cherchez est en fait une fonction de covariance qui est une fonction de timelag. Je fais de l'autocovariance comme ça:

 def autocovariance(Xi, N, k):
    Xs=np.average(Xi)
    aCov = 0.0
    for i in np.arange(0, N-k):
        aCov = (Xi[(i+k)]-Xs)*(Xi[i]-Xs)+aCov
    return  (1./(N))*aCov

autocov[i]=(autocovariance(My_wector, N, h))
1
Leukonoe

Comme indiqué ci-dessus, vous n'avez que deux vecteurs, vous n'aurez donc qu'une matrice de cov 2x2.

IIRC les 2 termes diagonaux principaux seront la somme ((x-moyenne (x)) ** 2)/(n-1) et de même pour y.

Les 2 termes hors diagonale seront la somme ((x-moyenne (x)) (y-moyenne (y)))/(n-1). n = 25 dans ce cas.

0
Stuart

selon le document, vous devez vous attendre à un vecteur variable dans la colonne:

If we examine N-dimensional samples, X = [x1, x2, ..., xn]^T

mais plus tard, il est dit que chaque ligne est une variable

Each row of m represents a variable.

vous devez donc saisir votre matrice comme transposée

x=np.random.normal(size=25)
y=np.random.normal(size=25)
X = np.array([x,y])
np.cov(X.T)

et selon wikipedia: https://en.wikipedia.org/wiki/Covariance_matrix

X is column vector variable
X = [X1,X2, ..., Xn]^T
COV = E[X * X^T] - μx * μx^T   // μx = E[X]

vous pouvez l'implémenter vous-même:

# X each row is variable
X = X - X.mean(axis=0)
h,w = X.shape
COV = X.T @ X / (h-1)
0
lbsweek