我正在使用来自神经成像的数据,并且由于数据量很大,我想为我的代码使用稀疏矩阵(scipy.sparse.lil_matrix或csr_matrix) .
特别是,我需要计算矩阵的伪逆以解决最小二乘问题 . 我找到了sparse.lsqr方法,但效率不高 . 有没有一种方法来计算Moore-Penrose的伪逆(对应于正常矩阵的pinv) .
我的矩阵A的大小约为600'000x2000,并且在矩阵的每一行中,我将具有0到4非零值 . 矩阵A的大小由体素x纤维束(白质纤维束)给出,我们期望在体素中最多穿过4个束 . 在大多数白质体素中,我们预计至少有1个道,但我会说大约20%的线可能是零 .
向量b不应该是稀疏的,实际上b包含每个体素的度量,通常不是零 .
我需要最小化错误,但是矢量x上也存在一些条件 . 当我在较小的矩阵上尝试模型时,我从不需要约束系统以满足这些条件(通常为0
有什么帮助吗?有没有办法避免采取A的伪逆?
谢谢
Update 1st June: 再次感谢您的帮助 . 我可以't really show you anything about my data, because the code in python give me some problems. However, in order to understand how I could choose a good k I'试图在Matlab中创建一个测试函数 .
代码如下:
F=zeros(100000,1000);
for k=1:150000
p=rand(1);
a=0;
b=0;
while a<=0 || b<=0
a=random('Binomial',100000,p);
b=random('Binomial',1000,p);
end
F(a,b)=rand(1);
end
solution=repmat([0.5,0.5,0.8,0.7,0.9,0.4,0.7,0.7,0.9,0.6],1,100);
size(solution)
solution=solution';
measure=F*solution;
%check=pinvF*measure;
k=250;
F=sparse(F);
[U,S,V]=svds(F,k);
s=svds(F,k);
plot(s)
max(max(U*S*V'-F))
for s=1:k
if S(s,s)~=0
S(s,s)=1/S(s,s);
end
end
inv=V*S'*U';
inv*measure
max(inv*measure-solution)
你知道与F的大小相比应该是什么?我已经花了250(超过1000)并且结果不令人满意(等待时间是可以接受的,但不是很短) . 现在我也可以将结果与已知解决方案进行比较,但是如何选择k呢?我还附上了我获得的250个单值的图,并将它们的正方形归一化 . 我不知道如何更好地在matlab中做一个screeplot . 我现在正在进行更大的k,以确定是否会突然显示该值会小得多 .
再次感谢,珍妮弗
2 回答
您可以更多地了解scipy.sparse.linalg中提供的替代方案 .
无论如何,请注意,稀疏矩阵的伪逆最有可能是(非常)密集的,因此在求解稀疏线性系统时,它并不是一个非常富有成效的途径(通常) .
您可能希望稍微更详细地描述您的特定问题(
dot(A, x)= b+ e
) . 至少指定:'typical'大小
A
'typical'
A
中非零条目的百分比最小二乘意味着
norm(e)
被最小化,但请指出您的主要兴趣是x_hat
还是b_hat
,其中e= b- b_hat
和b_hat= dot(A, x_hat)
Update :如果您对
A
的等级有了一些了解(并且它远小于列数),您可以尝试使用total least squares方法 . 这是一个简单的实现,其中k
是要使用的第一个奇异值和向量的数量(即'effective' rank) .无论我的评论的答案如何,我认为你可以使用Moore-Penrose SVD representation轻松地完成这个 . 使用scipy.sparse.linalg.svds找到SVD,用pseudoinverse替换Sigma,然后乘以V * Sigma_pi * U'找到原始矩阵的伪逆 .