寻找大矩阵最小二乘解的更快方法

4

我想找到矩阵的最小二乘解,我正在使用numpy的linalg.lstsq函数;

weights = np.linalg.lstsq(semivariance, prediction, rcond=None)

我的变量维度如下: semivariance是一个大小为5030 x 5030的浮点数。 prediction是一个长度为5030的一维数组。
我的问题是,返回weights的值需要大约80秒,并且我必须重复计算weights约10000次,因此计算时间很长。
是否有更快的方法或Python函数可以实现这一点?

我怀疑你在Python中无法击败numpy实现的速度,特别是因为C&Fortran已经完成了大部分工作。这很可能是目前最好的通用实现。你需要重新思考你的问题,这超出了SO的范围。 - FHTMitchell
由于semivariance是一个方阵,因此更快的方法是先将其求逆,然后使用dot乘积:weights = np.linalg.inv(semivariance).dot(prediction) - Brenlla
另外,我刚刚注意到你的系统是完全确定的,这种情况下最好使用solveweights = np.linalg.solve(semivariance, prediction)。以上两种方法都假定semivariance具有完整的秩。 - Brenlla
@user7436576,你在进行克里金插值吗? - Warren Weckesser
@WarrenWeckesser,是的。我正在进行克里金插值。 - user2554925
1个回答

3

@Brenlla 看起来是正确的,即使您使用Moore-Penrose伪逆矩阵进行最小二乘求解,它也比np.linalg.lstsq快得多:

import numpy as np
import time

semivariance=np.random.uniform(0,100,[5030,5030]).astype(np.float64)
prediction=np.random.uniform(0,100,[5030,1]).astype(np.float64)

start=time.time()
weights_lstsq = np.linalg.lstsq(semivariance, prediction, rcond=None)
print("Took: {}".format(time.time()-start))

>>> Took: 34.65818190574646

start=time.time()
weights_pseudo = np.linalg.solve(semivariance.T.dot(semivariance),semivariance.T.dot(prediction))
print("Took: {}".format(time.time()-start))

>>> Took: 2.0434153079986572

np.allclose(weights_lstsq[0],weights_pseudo)

>>> True

以上内容并非与您的精确矩阵相关,但示例上的概念可能具有可转移性。 np.linalg.lstsq执行优化问题,通过最小化|| b - a x ||^2来解决ax=b中的x。在极大矩阵上,这通常更快,因此线性模型通常使用神经网络中的梯度下降来解决,但在这种情况下,矩阵的大小不足以获得性能优势。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接