web-dev-qa-db-ja.com

numpy共分散行列

長さ25の2つのベクトルがあり、それらの共分散行列を計算するとします。私はnumpy.covでこれをやってみましたが、常に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]])

Rowvarフラグを使用しても効果はありません。まったく同じ結果が得られます。

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

25x25の共分散行列を取得するにはどうすればよいですか?

19
user13321

25個ではなく2個のベクターがあります。使用しているコンピューターにはpythonがないため、これをテストすることはできませんが、試してみてください。

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

もちろん....本当にあなたが欲しいものはおそらくもっと似ています:

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)

これは、num_vects 1x nベクトルの共分散(と思う/希望)を取ります。

11
David Marx

これを試して:

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

としてドキュメントを読んで、

>> np.cov.__doc__ 

または Numpy Covariance を見ると、Numpyは配列の各行を個別の変数として扱うため、2つの変数があるため、2 x 2の共分散行列が得られます。

前の投稿には正しい解決策があると思います。説明があります:-)

3
Arcturus

変更する必要があります

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

上に

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

取得したもの(2 x 2)は25 * 25よりも便利です。 XとYの共分散は、対称cov_matrixの非対角要素です。

私が役に立たないと思う(25 x 25)と主張するなら、なぜあなたは定義を書き出さないのですか?

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

サンプルベクトルからの共分散行列

2つのN次元ベクトルを使用して定義された共分散行列に関する小さな混乱を明確にするために、2つの可能性がありますです。

自問しなければならない質問は、次のことを考慮するかどうかです。

  • 1つの変数のN個の実現/サンプルとしての各ベクトル(たとえば、2つの3次元ベクトル[X1,X2,X3]および[Y1,Y2,Y3]。それぞれ変数XおよびYに対して3つの実現があります。 )
  • N個の変数に対して1つの実現としての各ベクトル(たとえば、2つの3次元ベクトル[X1,Y1,Z1]および[X2,Y2,Z2]。ベクトルごとに変数X、YおよびZに対して1つの実現があります。 )

共分散行列は、2つの異なる変数に基づく分散として直感的に定義されるため、

  • 最初のケースでは、2つの変数があり、それぞれにN個のサンプル値があるため、2x2行列になりますここで、変数ごとのN個のサンプルのおかげで共分散が計算されます
  • 2番目のケースでは、N個の変数があり、それぞれに2つのサンプルがあるため、NxN行列になります

Numpyを使用した実際の質問について

ベクトルごとに25個の変数があると考える場合(サンプルコードを簡素化するために25ではなく3を使用)、したがって、1つのベクトル内の複数の変数を1回実現するには、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

3つの変数を考慮したコードリターン:

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

それ以外の場合、1つのベクトルが1つの変数に対して25サンプルであると考える場合rowvar=1(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

2つの変数を考慮したコードリターン:

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

あなたが探しているのは、実際にはタイムラグ関数である共分散関数だと思います。私はそのような自己共分散をしています:

 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

上記で指摘したように、ベクトルは2つしかないため、2x2 cov行列のみを取得します。

IIRCの2つの主な対角項はsum((x-mean(x))** 2)/(n-1)で、yについても同様です。

2つの非対角項はsum((x-mean(x))(y-mean(y)))/(n-1)になります。この場合、n = 25。

0
Stuart

文書によると、列には可変ベクトルが必要です。

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

後で各行が変数であると言いますが

Each row of m represents a variable.

行列を転置として入力する必要があります

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

ウィキペディアによると: 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]

自分で実装できます:

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