2012-04-05 2 views
0

나는 원점을 중심으로 중심에 놓고 크기를 조정해야하는 데이터가 있습니다. 그런 다음 최대 분산의 방향이 x 축에 있도록 데이터를 회전해야합니다. 그런 다음 데이터의 평균과 공분산을 계산합니다. 공분산 행렬의 첫 번째 요소가 1이되어야합니다. 이것은 스케일링 팩터를 조정하여 이루어 졌다고 생각하지만 스케일링 팩터가 무엇인지 알아낼 수 없습니다.공분산 행렬의 첫 번째 요소가 1이되도록 배율 인수를 결정하는 방법은 무엇입니까?

데이터를 중앙에 배치하려면 평균을 제거하고 SVD를 사용하지만 크기 조정은 여전히 ​​내 문제입니다.

signature = numpy.loadtxt(name, comments = '%', usecols = (0,cols-1)) 
signature = numpy.transpose(signature) 

#SVD to get D so that data can be scaled by 1/(highest singular value in D) 
U, D, Vt = numpy.linalg.svd(signature , full_matrices=0) 
cs = utils.centerscale(signature, scale=False) 
signature = cs[0] 
#plt.scatter(cs[0][0],cs[0][1],color='r') 

#SVD so that data can be rotated so that direction of most variance is on x-axis 
U, D, Vt = numpy.linalg.svd(signature , full_matrices=0) 
cs = utils.centerscale(signature, center=False, scalefactor=D[0]) 
U, D, Vt = numpy.linalg.svd(cs[0] , full_matrices=0) 
D = numpy.diag(D) 
norm = numpy.dot(D,Vt) 

다음

는 규범의 평균 및 COV 결과의 예 (시험 예는 고해상도를 사용).

********************************************************************** 
Failed example: 
print numpy.mean(res, axis=1) 
Expected: 
[ 7.52074907e-18 -6.59917722e-18] 
Got: 
[ -1.22008884e-17 2.41126563e-17] 
********************************************************************** 
Failed example: 
print numpy.cov(res, bias=1) 
Expected: 
[[ 1.00000000e+00 9.02112676e-18] 
[ 9.02112676e-18 1.40592827e-01]] 
Got: 
[[ 4.16666667e-03 -1.57698124e-19] 
[ -1.57698124e-19 5.85803446e-04]] 
********************************************************************** 
1 items had failures: 
2 of 4 in __main__.processfile 
***Test Failed*** 2 failures. 

모든 값은 공분산 행렬의 첫 번째 요소를 제외하고는 관계가 없으며 1이어야합니다.

나는 어디에서나 시도해 보았으며 답을 찾을 수 없습니다. 어떤 도움을 주시면 감사하겠습니다.

답변

0

utils.centerscale이 무엇인지 알지 못합니다. 그러나 공분산 행렬의 왼쪽 위 항이 1이되도록 상수 요소로 행렬을 스케일하려는 경우 행렬을 스케일 없음의 공분산 용어의 제곱근 :

>>> import numpy 
>>> numpy.random.seed(17) 
>>> m = numpy.random.rand(5,4) 
>>> m 
array([[ 0.294665 , 0.53058676, 0.19152079, 0.06790036], 
     [ 0.78698546, 0.65633352, 0.6375209 , 0.57560289], 
     [ 0.03906292, 0.3578136 , 0.94568319, 0.06004468], 
     [ 0.8640421 , 0.87729053, 0.05119367, 0.65241862], 
     [ 0.55175137, 0.59751325, 0.48352862, 0.28298816]]) 
>>> c = numpy.cov(m,bias=1) 
>>> c 
array([[ 0.0288779 , 0.00524455, 0.00155373, 0.02779861, 0.01798404], 
     [ 0.00524455, 0.00592484, -0.00711072, 0.01006019, 0.00631144], 
     [ 0.00155373, -0.00711072, 0.13391344, -0.10551922, 0.00945934], 
     [ 0.02779861, 0.01006019, -0.10551922, 0.11250984, 0.00982862], 
     [ 0.01798404, 0.00631144, 0.00945934, 0.00982862, 0.01444482]]) 
>>> numpy.cov(m/c[0][0]**0.5, bias=1) 
array([[ 1.  , 0.18161135, 0.05380354, 0.96262562, 0.62276138], 
     [ 0.18161135, 0.20516847, -0.24623392, 0.3483699 , 0.21855613], 
     [ 0.05380354, -0.24623392, 4.63722877, -3.65397781, 0.32756326], 
     [ 0.96262562, 0.3483699 , -3.65397781, 3.89605297, 0.34035085], 
     [ 0.62276138, 0.21855613, 0.32756326, 0.34035085, 0.5002033 ]]) 

그러나 이것은 단순히 좌측 상단 회원 공분산 행렬을 분할 같은 효과가 있습니다 당신은 수도,

>>> (numpy.cov(m,bias=1)/numpy.cov(m,bias=1)[0][0])/(numpy.cov(m/c[0][0]**0.5, bias=1)) 
array([[ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.]]) 

당신이 무슨 일을하는지에 따라 또한 numpy.corrcoef에 관심이 있으시면 대신에 상관 계수 행렬을 사용합니다.

+0

감사합니다. 덕분에 많은 도움이되었습니다. – luke417

관련 문제