我正在编写一些涉及查找给定矩阵的特征向量的代码,并且很惊讶Ruby在简单的情况下会产生一些不合理的结果.
例如,以下矩阵具有与特征值1相关联的特征向量:
> m = Matrix[[0r, 1/2r, 1/2r, 1/3r],
             [0r,  0r,  1/4r, 1/3r],
             [0r, 1/4r,  0r,  1/3r],
             [1r, 1/4r, 1/4r,  0r]]
Ruby发现特征值足够好,但特征向量爆炸:
> m.eigen.eigenvalues[2]
=> 1.0000000000000009
m.eigen.eigenvectors[2]
=> Vector[5.957702309312754e+15, 5.957702309312748e+15, 5.957702309312743e+15, 5.957702309312753e+15]
实际的特征向量应为(7,4,4,9).
这不是麻烦吗?如果Ruby无法处理微小的矩阵,那么我们怎么能相信呢?或者我做错了什么?
我有一个非常大的稀疏矩阵,表示马尔可夫链中的过渡马赛克,即矩阵的每一行的总和等于1,我有兴趣找到第一个特征值及其相应的小于1的向量.我知道特征值在[-1,1]部分中有界,它们都是实数(非复数).
我试图使用python scipy.sparse.eigs函数计算值,但是,函数的一个参数是要估计的特征值/向量的数量,每次我增加要估计的参数数量时,特征值的数量就是精确的一个人也成长了.
不用说,我正在使用which带有值的参数'LR'为了得到k个最大的特征值,k是要估计的值的数量.
有没有人知道如何解决这个问题(找到小于1的第一个特征值及其相应的向量)?
我princomp在R中用来执行PCA.我的数据矩阵很大(10K x 10K,每个值最多4个小数点).在Xeon 2.27 GHz处理器上需要大约3.5小时和~6.5 GB的物理内存.
由于我只想要前两个组件,有没有更快的方法呢?
更新:
除了速度之外,还有一种内存有效的方法吗?
用于计算前两个组件需要大约2小时和~6.3 GB的物理内存svd(,2,).
我有一个~3000x3000协方差相似的矩阵,我在其上计算特征值 - 特征向量分解(它是一个OpenCV矩阵,我用来cv::eigen()完成工作).
但是,我实际上只需要前30个特征值/向量,我不关心其余的.从理论上讲,这应该可以显着加快计算速度,对吧?我的意思是,这意味着它有2970个需要计算的特征向量.
哪个C++库允许我这样做?请注意,OpenCV的eigen()方法确实有参数,但文档说它们被忽略了,我自己测试了,它们确实被忽略了:D
更新: 我设法用ARPACK做到了.我设法为Windows编译它,甚至使用它.结果看起来很有希望,在这个玩具示例中可以看到一个例子:
#include "ardsmat.h"
#include "ardssym.h"
int     n = 3;           // Dimension of the problem.
    double* EigVal = NULL;  // Eigenvalues.
    double* EigVec = NULL; // Eigenvectors stored sequentially.
    int lowerHalfElementCount = (n*n+n) / 2;
    //whole matrix:
    /*
    2  3  8
    3  9  -7
    8  -7 19
    */
    double* lower = new double[lowerHalfElementCount]; //lower half of the matrix
    //to be filled with COLUMN major (i.e. one column after the other, always …考虑奇异值分解M = USV*.然后,M*M的特征值分解给出M*M = V(S*S)V*= VS*U*USV*.我希望通过显示eigh函数返回的特征向量与函数返回的特征向量相同来验证numpy的这种相等svd性:
import numpy as np
np.random.seed(42)
# create mean centered data
A=np.random.randn(50,20)
M= A-np.array(A.mean(0),ndmin=2)
# svd
U1,S1,V1=np.linalg.svd(M) 
S1=np.square(S1)
V1=V1.T  
# eig
S2,V2=np.linalg.eigh(np.dot(M.T,M))
indx=np.argsort(S2)[::-1]
S2=S2[indx]
V2=V2[:,indx]
# both Vs are in orthonormal form
assert np.all(np.isclose(np.linalg.norm(V1,axis=1), np.ones(V1.shape[0])))
assert np.all(np.isclose(np.linalg.norm(V1,axis=0), np.ones(V1.shape[1])))
assert np.all(np.isclose(np.linalg.norm(V2,axis=1), np.ones(V2.shape[0])))
assert np.all(np.isclose(np.linalg.norm(V2,axis=0), np.ones(V2.shape[1])))
assert np.all(np.isclose(S1,S2))
assert np.all(np.isclose(V1,V2))
最后一个断言失败了.为什么?
我正在尝试计算几个 (5-500) 特征向量,这些特征向量对应于大型对称方形稀疏矩阵(高达 30000x30000)的最小特征值,其中非零值小于 0.1%。
我目前在 shift-invert 模式 (sigma=0.0) 下使用 scipy.sparse.linalg.eigsh,我通过有关该主题的各种帖子发现这是首选解决方案。但是,在大多数情况下,解决问题最多需要 1 小时。另一方面,如果我要求最大的特征值(在我的系统上为亚秒),则该函数非常快,这是文档中预期的。
由于我在工作中更熟悉 Matlab,所以我尝试在 Octave 中解决这个问题,使用 eigs (sigma=0) 在短短几秒钟内(低于 10 秒)给了我相同的结果。由于我想对包括特征向量计算在内的算法进行参数扫描,因此在 python 中也能获得这种时间增益。
我首先更改了参数(尤其是容差),但在时间尺度上并没有太大变化。
我在 Windows 上使用 Anaconda,但试图将 scipy 使用的 LAPACK/BLAS(这是一个巨大的痛苦)从 mkl(默认 Anaconda)切换到 OpenBlas(根据文档由 Octave 使用),但看不到变化表现。
我无法弄清楚,使用的 ARPACK 是否有改变(以及如何改变)?
我将以下代码的测试用例上传到以下 dropbox 文件夹:https ://www.dropbox.com/sh/l6aa6izufzyzqr3/AABqij95hZOvRpnnjRaETQmka?dl =0
在 Python 中
import numpy as np
from scipy.sparse import csr_matrix, csc_matrix, linalg, load_npz   
M = load_npz('M.npz')
evals, evecs = linalg.eigsh(M,k=6,sigma=0.0)
在八度:
M=dlmread('M.txt');
M=spconvert(M);
[evecs,evals] = eigs(M,6,0);
任何帮助是appriciated !
我根据评论和建议尝试了一些其他选项:
Octave: 
eigs(M,6,0)并eigs(M,6,'sm') …
我有这个矩阵A,表示图像像素强度的相似性.例如:考虑10 x 10图像.在这种情况下,矩阵A具有尺寸100 x 100,并且元素A(i,j)将具有0到1范围内的值,表示像素i与j在强度方面的相似性.
我使用OpenCV进行图像处理,开发环境是Linux上的C语言.
目标是计算矩阵A的特征向量,我使用了以下方法:
static CvMat mat, *eigenVec, *eigenVal;
static double A[100][100]={}, Ain1D[10000]={};
int cnt=0;
//Converting matrix A into a one dimensional array
//Reason: That is how cvMat requires it
for(i = 0;i < affnDim;i++){
  for(j = 0;j < affnDim;j++){
 Ain1D[cnt++] = A[i][j];
  }
}
mat = cvMat(100, 100, CV_32FC1, Ain1D); 
cvEigenVV(&mat, eigenVec, eigenVal, 1e-300);
for(i=0;i < 100;i++){
  val1 = cvmGet(eigenVal,i,0); //Fetching Eigen Value
  for(j=0;j < 100;j++){   
 matX[i][j] = cvmGet(eigenVec,i,j); //Fetching each component …我在Matlab上使用了一个函数:
[V,D] = eig(C);
我看到V和D总是按升序排序.它是否总是那样,或者我应该在获得V和D价值后对它们进行排序?
我已经搜索过很多但是我找不到任何关于两种方法'eig'和'eigs'如何不同的答案.从它们收到的特征值和特征向量之间有什么区别?
我将解释我想要做什么,因为它似乎与理解我的问题有关.
我目前正在尝试基于数据库中的已知图片对在摄像机前面的人进行人脸识别.
这些已知图片是从识别智能卡(其仅包含单个正面图片)或来自社交网络的正面脸部图片中收集的.从我到目前为止所看到的情况来看,似乎要获得良好的人脸识别,需要大量的训练图像(50+).因此,由于我收集的图像很少能够创建可靠的训练集,所以我尝试使用我的实时相机帧捕获(当前使用150)作为训练集,并且先前收集的识别图像作为测试集.我不确定我正在尝试的是否正确,所以如果我搞砸了,请告诉我.
所以,问题是,在我说了之后,我从智能卡中找到了5张识别出来的图片,我尝试使用相机拍摄的150帧作为训练集进行人脸识别.当试图识别时,5个测试面中每个测试面的置信度值非常相似,使得整个程序无用,因为我无法准确识别任何人.通常,使用不同的相机捕捉作为训练我从随机人物的照片中获得比自己的照片更高的置信度值.
我很感激你能给我的任何帮助,因为我在这里不知所措.
谢谢.
注意:我正在使用OpenCV的JavaCV包装器来创建我的程序,以及包中包含的haarcascades.特征脸是使用的算法.