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]]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误提示意味着numpy的线性代数库在进行奇异值分解(SVD)时没有收敛,即算法无法得出稳定的结果。 通常,出现这个错误的原因可能是矩阵过大,或者矩阵中有过多的奇异值,使得算法无法正确处理。解决这个问题的方法可能包括使用更高效的奇异值分解算法,或者对矩阵进行预处理以减少奇异值的数量。 此外,还有可能是数据本身存在问题,例如有缺失值或异常值,也可能导致奇异值分解失败。在这种情况下,需要先对数据进行处理或清洗,以便能够正确地进行奇异值分解。 ### 回答2: numpy.linalg.linalgerror: svd did not converge。这个错误是在进行矩阵奇异值分解(Singular Value Decomposition,SVD)时出现的。SVD是矩阵分解的一种方法,它将任何矩阵分解成三个矩阵的积:一个左奇异矩阵、一个右奇异矩阵和一个对角线上是奇异值(Singular Value)的矩阵。 在使用SVD时,会遇到奇异矩阵无法收敛的情况,这种情况非常罕见,一般是由于矩阵的性质不够好。在实际应用中,通常可以通过以下几种方式来解决这个问题: 1. 检查数据的有效性:在使用SVD进行分解之前,应该检查数据是否有明显的异常值、缺失值或者不完整的数据。如果出现了这些问题,很可能会导致SVD无法收敛。需要对数据进行清理和处理。 2. 减小矩阵的维度:如果矩阵的维度非常高,可以考虑通过特征提取或者降维的方式来降低矩阵的维度,从而使SVD更容易收敛。 3. 选择其他的奇异值分解方法:如果SVD无法收敛,可以尝试使用其他的矩阵分解方法,比如QR分解或者LU分解。 4. 调整参数:在使用SVD时,可以尝试调整一些参数,比如tol、max_iter等参数,从而使算法更容易收敛。 总之,numpy.linalg.linalgerror: svd did not converge这个错误出现的原因比较复杂,需要具体情况具体分析。在实际应用中,需要仔细检查数据和算法,然后尝试不同的解决方案,才能解决这个问题。 ### 回答3: numpy.linalg.linalgerror: svd did not converge 是一个 numpy 包中出现的错误提示信息,表明了在进行奇异值分解(SVD)操作过程中,该操作无法达到收敛状态。奇异值分解是一种矩阵分解方式,用于找到一个矩阵的奇异值和奇异向量。这个分解方式在数学上非常重要,被广泛用于科学计算和工程领域。 SVD 的算法是一个迭代式的过程,在过程中会对矩阵进行逐步缩减,直到矩阵达到一个指定的阈值或者收敛状态。当出现 numpy.linalg.linalgerror: svd did not converge 这个错误提示时,说明在迭代过程中,矩阵没有收敛,可能有以下几个原因: 1. 矩阵过于复杂:在进行奇异值分解时,可能会碰到一些非常复杂的矩阵,这些矩阵的特征值和特征向量十分复杂,从而导致分解过程无法收敛。 2. 矩阵过于稀疏:如果矩阵中有很多零元素,可能会导致在进行 SVD 分解过程中,迭代过程过于复杂,从而导致无法收敛。 3. 不同的矩阵分解算法:SVD 算法有多种不同的实现方式,在不同的实现方式中,可能会出现收敛性能差异,可能导致某些算法无法达到目标收敛精度。 如果出现了这个错误提示,我们可以尝试以下方法: 1. 调整收敛阈值:运行时,可以尝试调整收敛的阈值,适当降低该值,从而使得 SVD 分解过程加速收敛。 2. 使用其他算法:如果使用的 SVD 算法无法收敛,可以尝试使用其他的矩阵分解算法,如 QR 分解、LU 分解等。 3. 增大计算精度:通过提高计算精度,可以使得 SVD 分解过程更加稳定,降低迭代过程中的收敛难度。 numpy.linalg.linalgerror: svd did not converge 这个错误提示表明了在进行 SVD 分解过程中出现的问题,使用以上方法可以帮助我们解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值