2016-07-19 8 views
3

공분산 Cnp 수량을 계산하고 싶습니다. 각 개별 수량 측정에는 자체 무게가 주어집니다. 즉, 내 무게 배열 W의 모양이 내 수량 배열 Q (nx)과 동일합니다. 네이티브 np.cov() 함수는 개별 측정에 제공된 가중치 (즉, 길이가 n 인 벡터) 만 지원합니다.numpy의 가중 공분산 행렬

pp 행렬로 초기화하고 반복 할 수 있지만 p이 큰 경우 매우 느립니다. Q 이후

각각 양 (Q의 열)에 대한 제로 평균을 갖는 것으로 알려져있다, I는 분자가 Q[:, i] * W[:, i] * Q[:, j] * W[:, j]이어야 재정렬하면 C의 각 요소에 대한 명시적인 공식은

C[i,j] = np.sum(
    Q[:, i] * Q[:, j] * W[:, i] * W[:, j])/np.sum(W[:, i] * W[:, j]) 

이다 그것은 I 같아 Q * W의 열을 곱하고 합계 할 수 있어야하며, 마찬가지로 분모를 수행해야합니다 (W * W 제외).

np.einsum()과 함께 할 방법이 있습니까?

테스트를 들어, 다음과 같이 정의 할 수 있습니다 :

C = array([[ 1. , 0.1 , 0.2 ], # set this beforehand, to test whether 
      [ 0.1 , 0.5 , 0.15], # we get the correct result 
      [ 0.2 , 0.15, 0.75]]) 

Q = array([[-0.6084634 , 0.16656143, -1.04490324], 
      [-1.51164337, -0.96403094, -2.37051952], 
      [-0.32781346, -0.19616374, -1.32591578], 
      [-0.88371729, 0.20877833, -0.52074272], 
      [-0.67987913, -0.84458226, 0.02897935], 
      [-2.01924756, -0.51877396, -0.68483981], 
      [ 1.64600477, 0.67620595, 1.24559591], 
      [ 0.82554885, 0.14884613, -0.15211434], 
      [-0.88119527, 0.11663335, -0.31522598], 
      [-0.14830668, 1.26906561, -0.49686309]]) 

W = array([[ 1.01133857, 0.91962164, 1.01897898], 
      [ 1.09467975, 0.91191381, 0.90150961], 
      [ 0.96334661, 1.00759046, 1.01638749], 
      [ 1.04827001, 0.95861001, 1.01248969], 
      [ 0.91572506, 1.09388218, 1.03616461], 
      [ 0.9418178 , 1.07210878, 0.90431879], 
      [ 1.0093642 , 1.00408472, 1.07570172], 
      [ 0.92203074, 1.00022631, 1.09705542], 
      [ 0.99775598, 0.01000000, 0.94996408], 
      [ 1.02996389, 1.01224303, 1.00331465]]) 

답변

1
당신은 np.dot으로 매우 효율적인 행렬 곱셈을 사용할 수 있습니다

-

QW = Q*W 
C = QW.T.dot(QW)/W.T.dot(W) 
+0

네가 맞아,이 시계는 내 방법보다 ~ 3 배 빠릅니다. 100x10 배열이고, 그 요소는'Q'와'W'의 크기로 커집니다. – DathosPachy

1

좀 더 실험 후, 내가 찾은 그 다음 작품 :

A = np.einsum('ki,kj->ij', Q*W, Q*W) 
B = np.einsum('ki,kj->ij', W, W) 
C = A/B