今天在看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);
按照降序排序,修改u和v矩阵
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]]