当前位置:首页 » 操作系统 » svd算法

svd算法

发布时间: 2022-01-31 23:41:08

‘壹’ 请问matlab中svd的算法是什么 propack中求解svd的命令lansvd的算法是什么 二者的优劣比较傲~~

哈哈,我也在做LJ数值分析大作业。。提示你用help和type命令~

‘贰’ 基于svd人脸识别

哈,潘时七,加紧给分哦有``

‘叁’ 如何将SVD算法用maprece实现

数据挖掘比赛算法
examples/src/main/java/org/apache/mahout/cf/taste/example/kddcup/track1/svd

推荐系统中利用SVD实现降维
core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/svd

‘肆’ 用MATLAB计算这个矩阵的SVD,怎样操作

以matlab7.1为例,
在command中
>> a=0;

后用数据编辑器打开,把Excel中的数据过来,直接粘贴就行.
再在command中
>> [U V D]= svd( a )

至于U V D:(假设a 为m*n 的矩阵),则
U ,m*m的酉矩阵
D ,n*n的酉矩阵
V ,m*n的矩阵

a = U*V*D 即为奇异值分解..

更详细的说明,请看矩阵分析的相关资料.....

‘伍’ svd数据点计算完成后如何计算相似度

首先根据Bob=[-0.3775,0.0802],用cosin算法计算出与Bob最相似的用户,假如最后Jorbe与Bob最
相似,Jorbe的评分数据为 [5 4 5 0 4 5],,由Jorbe 的评分数据可以看出,他只有第4项数据没有评
分,而Bob有第3、4、5项数据没有评分,所以就可以根据Jorbe的评分数据来预测Bob的评分数
据,这里就可以预测Bob的第3、5项评分数据为5、4。

‘陆’ Matlab 的 svd 是怎么实现的

在MATLAB里打开svd的源码可以看到只有一堆注释,最后写的是该函数为built-in function。事实上,MATLAB的矩阵计算使用的是Intel的MKL库,这个库基本是现有BLAS/LAPACK实现中最快的了。svd是LAPACK中的标准运算,因此MATLAB实际是使用的MKL库来做svd。
MKL作为一个商业库,其算法细节和代码是不公开的,而且业界对于这种基本算法必然会有非常独到的优化,涉及到大量细节(算法本身的细节,以及代码层次的细节)。svd的经典算法有Golub-Kahan算法、分治法、Jacobi法几种,我推测MKL具体实现的是分治法。

‘柒’ 怎么样用matlab的svd算法处理一个稀疏矩阵

确实有点大的 两个指定顶点之间的最短路径 问题如下:给出了一个连接若干个城镇的铁路网络,在这个网络的两个指定城镇间,找一条最短铁路线。 以各城镇为图G的顶点,两城镇间的直通铁路为图G相应两顶点间的边,得图G。对 G的每一边e...

‘捌’ 求SVD算法的C++实现代码

/** C++ function for SVD
函数原型:
bool svd(vector<vector<double> > A, int K, std::vector<std::vector<double> > &U, std::vector<double> &S, std::vector<std::vector<double> > &V);
其中
A是输入矩阵,假设A的维数是m*n,那么本函数将A分解为U diag(S) V'
其中U是m*K的列正交的矩阵. V是n*K的列正交矩阵,S是K维向量。K由第二个参数指定。
U的第i列是A的第i大奇异值对应的左歧义向量,S[i]=A的第 i大奇异值,V的第i列是A的第i大奇异值对应的右歧义响亮.
K是需要分解的rank,0<K<=min(m,n)

本程序采用的是最基本幂迭代算法,在linux g++下编译通过
**/


#include <cmath>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <vector>
using namespace std;
const int MAX_ITER=100000;
const double eps=0.0000001;

double get_norm(double *x, int n){
double r=0;
for(int i=0;i<n;i++)
r+=x[i]*x[i];
return sqrt(r);
}
double normalize(double *x, int n){
double r=get_norm(x,n);
if(r<eps)
return 0;
for(int i=0;i<n;i++)
x[i]/=r;
return r;
}

inline double proct(double*a, double *b,int n){
double r=0;
for(int i=0;i<n;i++)
r+=a[i]*b[i];
return r;
}
void orth(double *a, double *b, int n){//|a|=1
double r=proct(a,b,n);
for(int i=0;i<n;i++)
b[i]-=r*a[i];

}


bool svd(vector<vector<double> > A, int K, std::vector<std::vector<double> > &U, std::vector<double> &S, std::vector<std::vector<double> > &V){
int M=A.size();
int N=A[0].size();
U.clear();
V.clear();
S.clear();
S.resize(K,0);
U.resize(K);
for(int i=0;i<K;i++)
U[i].resize(M,0);
V.resize(K);
for(int i=0;i<K;i++)
V[i].resize(N,0);


srand(time(0));
double *left_vector=new double[M];
double *next_left_vector=new double[M];
double *right_vector=new double[N];
double *next_right_vector=new double[N];
while(1){
for(int i=0;i<M;i++)
left_vector[i]= (float)rand() / RAND_MAX;
if(normalize(left_vector, M)>eps)
break;
}
int col=0;
for(int col=0;col<K;col++){
double diff=1;
double r=-1;
for(int iter=0;diff>=eps && iter<MAX_ITER;iter++){
memset(next_left_vector,0,sizeof(double)*M);
memset(next_right_vector,0,sizeof(double)*N);
for(int i=0;i<M;i++)
for(int j=0;j<N;j++)
next_right_vector[j]+=left_vector[i]*A[i][j];

r=normalize(next_right_vector,N);
if(r<eps) break;
for(int i=0;i<col;i++)
orth(&V[i][0],next_right_vector,N);
normalize(next_right_vector,N);

for(int i=0;i<M;i++)
for(int j=0;j<N;j++)
next_left_vector[i]+=next_right_vector[j]*A[i][j];
r=normalize(next_left_vector,M);
if(r<eps) break;
for(int i=0;i<col;i++)
orth(&U[i][0],next_left_vector,M);
normalize(next_left_vector,M);
diff=0;
for(int i=0;i<M;i++){
double d=next_left_vector[i]-left_vector[i];
diff+=d*d;
}

memcpy(left_vector,next_left_vector,sizeof(double)*M);
memcpy(right_vector,next_right_vector,sizeof(double)*N);
}
if(r>=eps){
S[col]=r;
memcpy((char *)&U[col][0],left_vector,sizeof(double)*M);
memcpy((char *)&V[col][0],right_vector,sizeof(double)*N);
}else
break;
}
delete [] next_left_vector;
delete [] next_right_vector;
delete [] left_vector;
delete [] right_vector;

return true;
}

void print(vector<vector<double> > &A){
for(int i=0;i<A.size();i++){
for(int j=0;j<A[i].size();j++){
cout<<setprecision(3)<<A[i][j]<<' ';
}
cout<<endl;
}
}
int main(){
int m=10;
int n=5;
srand(time(0));
vector<vector<double> > A;
A.resize(m);

for(int i=0;i<m;i++){
A[i].resize(n);
for(int j=0;j<n;j++)
A[i][j]=(float)rand()/RAND_MAX;
}
print(A);
cout<<endl;

vector<vector<double> > U;
vector<double> S;
vector<vector<double> > V;
svd(A,2,U,S,V);
cout<<"U="<<endl;
print(U);
cout<<endl;
cout<<"S="<<endl;
for(int i=0;i<S.size();i++){
cout<<S[i]<<' ';
}
cout<<endl;
cout<<"V="<<endl;
print(V);
return 0;
}


‘玖’ SVD分解为什么是最好的QR分解和SVD比较LU呢SVD并行算法可行么

鉴于矩阵的奇异值分解SVD在工程领域的广泛应用(如数据压缩、噪声去除、数值分析等等,包括在NLP领域的潜在语义索引LSI核心操作也是SVD),今天就详细介绍一种SVD的实现方法--Jacobi旋转法。跟其它SVD算法相比,Jacobi法精度高,虽然速度慢,但容易并行实现。
基于双边Jacobi旋转的奇异值分解算法

V是A的右奇异向量,也是的特征向量;

U是A的左奇异向量,也是的特征向量。

特别地,当A是对称矩阵的时候,=,即U=V,U的列向量不仅是的特征向量,也是A的特征向量。这一点在主成分分析中会用到。

对于正定的对称矩阵,奇异值等于特征值,奇异向量等于特征向量。

U、V都是正交矩阵,满足矩阵的转置即为矩阵的逆。

双边Jacobi方法本来是用来求解对称矩阵的特征值和特征向量的,由于就是对称矩阵,求出的特征向量就求出了A的右奇异值,的特征值开方后就是A的奇异值。

一个Jacobi旋转矩阵J形如:

它就是在一个单位矩阵的基础上改变p行q行p列q列四个交点上的值,J矩阵是一个标准正交矩阵。

当我们要对H和p列和q列进行正交变换时,就对H施行:

在一次迭代过程当中需要对A的任意两列进行一次正交变换,迭代多次等效于施行

迭代的终止条件是为对角矩阵,即原矩阵H进过多次的双边Jacobi旋转后非对角线元素全部变成了0(实现计算当中不可能真的变为0,只要小于一个很小的数就可以认为是0了)。

每一个J都是标准正交阵,所以也是标准正交阵,记为V,则是,则。从此式也可以看出对称矩阵的左奇异向量和右奇异向量是相等的。V也是H的特征向量。

当特征值是0时,对应的Ui和Vi不用求,我们只需要U和V的前r列就可以恢复矩阵A了(r是非0奇异值的个数),这也正是奇异值分解可以进行数据压缩的原因。

+ View Code
基于单边Jacobi旋转的SVD算法

相对于双边,单边的计算量小,并且容易并行实现。

单边Jacobi方法直接对原矩阵A进行单边正交旋转,A可以是任意矩阵。

同样每一轮的迭代都要使A的任意两列都正交一次,迭代退出的条件是B的任意两列都正交。

单边Jacobi旋转有这么一个性质:旋转前若,则旋转后依然是;反之亦然。

把矩阵B每列的模长提取出来,,把记为V,则。

+ View Code
基于单边Jacobi旋转的SVD并行算法

单边Jacobi之于双边Jacobi的一个不同就是每次旋转只影响到矩阵A的两列,因经很多列对的正交旋转变换是可以并行执行的。

基本思想是将A按列分块,每一块分配到一个计算节点上,块内任意两列之间进行单边Jacobi正交变换,所有的计算节点可以同时进行。问题就是矩阵块内部列与列之间进行正交变换是不够的,我们需要所有矩阵块上的任意两列之间都进行正交变换,这就需要计算节点之间交换矩阵的列。本文采用奇偶序列的方法
由于这次我用的是C版的MPI(MPI也有C++和Fortan版的),所以上面代码用到的C++版的matrix.h就不能用了,需要自己写一个C版的matrix.h。

matrix.h

+ View Code
svd.c

+ View Code

‘拾’ 怎么在推荐系统中使用svd算法

SVD算法 SVD算法可用来求解大多数的线性最小二乘法问题. SVD 算法基于如下分解定理:对任 意的矩阵 Am ×n ,当其行数 m 大于等于列数 n 时,可以分解为正交矩阵 Um ×n , 非负对角矩阵 Wn×n以及正交矩阵Vn×n的转置的乘积,即 Am×n = Um×n ·[diag(

热点内容
sqlserveronlinux 发布:2024-09-19 08:16:54 浏览:253
编程常数 发布:2024-09-19 08:06:36 浏览:950
甘肃高性能边缘计算服务器云空间 发布:2024-09-19 08:06:26 浏览:161
win7家庭版ftp 发布:2024-09-19 07:59:06 浏览:715
数据库的优化都有哪些方法 发布:2024-09-19 07:44:43 浏览:268
知乎华为编译器有用吗 发布:2024-09-19 07:32:20 浏览:617
访问虚拟机磁盘 发布:2024-09-19 07:28:13 浏览:668
原地工作算法 发布:2024-09-19 07:28:07 浏览:423
如何设置linux的ip地址 发布:2024-09-19 07:22:25 浏览:750
微信忘记密码如何修改密码 发布:2024-09-19 07:05:07 浏览:80