2016.4.8 svd实现

今天在看ml的基础知识,其中想练练手,就拿python实现svd,其中遇上了诸多问题,好多之前的坑都忘记了,再次记录一下。

第一个是再数组拷贝的过程中,实际上只是地址拷贝,我一直就找不到原因,后来才想起来。

第二个是argsort的时候默认是从小到大,如果想要倒序,那么就再最开始的时候乘上-1.

 

 

import numpy as np

随便生成一个矩阵

A = np.random.rand(5,3)

shape = np.shape(A);

左右两边的需要求特征值和特征向量的矩阵

left = np.dot(A,A.transpose());

right = np.dot(A.transpose(),A);

求特征值和特征向量

[left_lambda,left_vector] = np.linalg.eig(left);

[right_lambda,right_vector] = np.linalg.eig(right);

 

申请新的空间!!!

U = np.zeros(np.shape(left_vector));

V = np.zeros(np.shape(right_vector));

D = np.zeros(shape);

 

按照降序排序,修改uv矩阵

sorted_ind = np.argsort(-left_lambda);

for i in range(0,len(sorted_ind)):

    U[:,i] = left_vector[:,sorted_ind[i]];

 

 

sorted_ind = np.argsort(-right_lambda);

for i in range(0,len(sorted_ind)):

    V[:,i] = right_vector[:,sorted_ind[i]];

 

寻找长度较小的那个维度

ind = 0;

for i in range(1,len(shape)):

    if shape[i]<shape[ind]:

        ind = i;

 

声称d矩阵

if ind == 0:

    sorted_ind = np.argsort(-left_lambda);

else:

    sorted_ind = np.argsort(-right_lambda);

   

for i in range(0,shape[ind]):

    if ind == 0:

        D[i,i] = np.sqrt(left_lambda[sorted_ind[i]]);

    else:

        D[i,i] = np.sqrt(right_lambda[sorted_ind[i]]);

 

 

输出信息

print;

print(U);

print;

print(D);

print;

print(-1*V.transpose());

print;

 

print(A);

print;

print(np.dot(U,np.dot(D,-1*V.transpose())));

print;

 

[Ustandard , Dstandard , VTstandard] = np.linalg.svd(A);

print(Ustandard);

print(Dstandard);

print(VTstandard);

 


运行结果:

U:

[[-0.5199467  -0.28721247 -0.23588695 -0.34774361 -0.34774361]

 [-0.38816823 -0.43667718 -0.26875727 -0.20742437 -0.20742437]

 [-0.5820713   0.67275354 -0.30983354  0.28823642  0.28823642]

 [-0.29116486 -0.49213994  0.25879655  0.68368212  0.68368212]

 [-0.39420411  0.17894971  0.84211306 -0.26766507 -0.26766507]]

D:

[[ 2.19946679  0.          0.        ]

 [ 0.          0.66454217  0.        ]

 [ 0.          0.          0.29816657]

 [ 0.          0.          0.        ]

 [ 0.          0.          0.        ]]

VT:

[[-0.51742165 -0.58322907 -0.62619381]

 [ 0.44458665 -0.80847082  0.38563927]

 [-0.73117546 -0.0788593   0.67761616]]

A:

[[ 0.55829652  0.82683905  0.59485454]

 [ 0.37133308  0.73886928  0.36841198]

 [ 0.92873744  0.39251661  0.91149184]

 [ 0.12953885  0.63182765  0.32718462]

 [ 0.31790393  0.38973843  0.75893705]]

U*D*VT:

[[ 0.55829652  0.82683905  0.59485454]

 [ 0.37133308  0.73886928  0.36841198]

 [ 0.92873744  0.39251661  0.91149184]

 [ 0.12953885  0.63182765  0.32718462]

 [ 0.31790393  0.38973843  0.75893705]]

standard svd : numpy.linalg.svd

[[-0.5199467  -0.28721247  0.23588695 -0.26996592 -0.72016677]

 [-0.38816823 -0.43667718  0.26875727 -0.35833428  0.67676033]

 [-0.5820713   0.67275354  0.30983354  0.30544933  0.13892286]

 [-0.29116486 -0.49213994 -0.25879655  0.77790685  0.03010951]

 [-0.39420411  0.17894971 -0.84211306 -0.31666478  0.05611721]]

[ 2.19946679  0.66454217  0.29816657]

[[-0.51742165 -0.58322907 -0.62619381]

 [ 0.44458665 -0.80847082  0.38563927]

 [ 0.73117546  0.0788593  -0.67761616]]

你可能感兴趣的:(2016.4.8 svd实现)