ti-enxame.com

matriz de covariância numpy

Suponha que eu tenha dois vetores de comprimento 25 e queira calcular sua matriz de covariância. Eu tento fazer isso com numpy.cov, mas sempre acabo com uma matriz 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]])

Usar o sinalizador rowvar também não ajuda - recebo exatamente o mesmo resultado.

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

Como posso obter a matriz de covariância 25x25?

19
user13321

Você tem dois vetores, não 25. O computador em que estou não possui python, portanto, não posso testar isso, mas tente:

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

Claro .... realmente o que você quer é provavelmente mais como:

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)

Isso requer a covariância (acho/espero) de num_vects 1x n vetores

11
David Marx

Tente o seguinte:

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

Lendo a documentação como,

>> np.cov.__doc__ 

ou olhando para Numpy Covariance , Numpy trata cada linha da matriz como uma variável separada, então você tem duas variáveis ​​e, portanto, obtém uma matriz de covariância 2 x 2.

Eu acho que o post anterior tem a solução certa. Eu tenho a explicação :-)

3
Arcturus

Você deveria mudar

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

para

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

O que você obteve (2 por 2) é mais útil que 25 * 25. A covariância de X e Y é uma entrada fora da diagonal na cov_matrix simétrica.

Se você insiste em (25 por 25) o que acho inútil, por que não escreve a definição?

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

Matriz de covariância a partir de vetores de amostras

Para esclarecer a pequena confusão sobre o que é uma matriz de covariância definida usando dois vetores N-dimensionais, existem duas possibilidades.

A pergunta que você deve fazer é se você considera:

  • cada vetor como N realizações/amostras de uma única variável (por exemplo, dois vetores tridimensionais [X1,X2,X3] e [Y1,Y2,Y3], onde você tem 3 realizações para as variáveis ​​X e Y, respectivamente)
  • cada vetor como 1 realização para N variáveis (por exemplo, dois vetores tridimensionais [X1,Y1,Z1] e [X2,Y2,Z2], onde você tem 1 realização para as variáveis ​​X, Y e Z por vetor)

Como uma matriz de covariância é definida intuitivamente como uma variação com base em duas variáveis ​​diferentes:

  • no primeiro caso, você tem 2 variáveis, N valores de exemplo para cada um, então você acaba com uma matriz 2x2 onde as covariâncias são calculadas graças a N amostras por variável
  • no segundo caso, você tem N variáveis, 2 amostras para cada uma, então você acaba com uma matriz NxN

Sobre a pergunta real, usando numpy

se você considerar que possui 25 variáveis ​​por vetor (levou 3 em vez de 25 para simplificar o código de exemplo), portanto, uma realização para várias variáveis ​​em um vetor, use 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

Código retorna, considerando 3 variáveis:

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

caso contrário, se você considerar que um vetor tem 25 amostras para uma variável, use rowvar=1 (parâmetro padrão do 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

Código retorna, considerando 2 variáveis:

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

Suponho que o que você está procurando é realmente uma função de covariância que é uma função de marca de tempo. Estou fazendo autocovariância assim:

 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

Como apontado acima, você tem apenas dois vetores e, portanto, terá apenas uma matriz cov 2x2.

IIRC, os dois principais termos diagonais serão soma ((média x (x)) ** 2)/(n-1) e da mesma forma para y.

Os 2 termos fora da diagonal serão soma ((média x (x)) (média y (y)))/(n-1). n = 25 neste caso.

0
Stuart

de acordo com o documento, você deve esperar um vetor variável na coluna:

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

embora mais tarde diga que cada linha é uma variável

Each row of m represents a variable.

então você precisa inserir sua matriz como transposta

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

e de acordo com a 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]

você pode implementá-lo você mesmo:

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