在Python中求解矩阵方程的有效方法

时间:2018-07-02 19:46:43

标签: python performance numpy matrix

现在,我正在使用numpy.linalg.solve来求解矩阵,但是实际上我正在使用它来求解5000 * 17956矩阵,这确实很耗时。它运行非常缓慢,花了我一个多小时才解决。用于求解矩阵方程的运行时间可能为O(n ^ 3),但我从未想到过会这么慢。有什么方法可以在Python中更快地解决它?

我的代码类似于这样,以解决方程BT * UT = BT*B a的问题,其中m是测试用例的数量(在我的情况下超过5000),B是数据矩阵m*17956,而u1*m

C = 0.005                        # hyperparameter term for regulization
I = np.identity(17956)          # 17956*17956 identity matrix
rhs = np.dot(B.T, U.T)          # (17956*m) * (m*1)     = 17956*1
lhs = np.dot(B.T, B)+C*I        # (17956*m) * (m*17956) = 17956*17956
a = np.linalg.solve(lhs, rhs)   # B.T u = B.T B a, solve for a (17956*1)

2 个答案:

答案 0 :(得分:2)

更新(2018年7月2日)::更新后的问题询问正则项的影响以及矩阵中数据的类型。总的来说,这可能会对特定CPU最优化的数据类型产生巨大影响(粗略的经验法则,在所有其他条件都很好的情况下,AMD最好使用矢量化整数数学,而Intel可以使用矢量化浮点数学更好)保持相等),并且大量零值的存在可以允许使用稀疏矩阵库。但是,在这种特殊情况下,主对角线的变化(远低于所考虑的所有值的1%)对运行时间的影响可以忽略不计。

TLDR;

  • 一个小时是合理的(三次回归表明,这在我的机器上-一台低端的chromebook上大约需要83分钟)。
  • 生成lhsrhs的预处理几乎没有用完。
  • numpy.linalg.solve相比,您将无法更快地解决确切的问题
  • 如果m很小,并且B是可逆的,那么您可以在一分钟或更短的时间内求解方程U.T=Ba
  • 如果这是一个较大问题的一部分,那么可以从数学框架简化此昂贵的中间步骤。
  • 性能瓶颈确实应该通过分析来解决,以找出导致问题的原因。
  • 由于这是来自现实世界的数据,因此根据最终目标,您也许可以使用更少的功能(直接或通过诸如PCA,NMF或LLE的简化步骤)逃脱。
  • 如另一个答案中所述,如果矩阵足够稀疏,则可以摆脱稀疏的线性代数例程,从而发挥很大的作用(许多自然语言处理数据源都是这样的)。
  • 由于输出是一维矢量,因此我将使用np.dot(U, B).T而不是np.dot(B.T, U.T)。移调整齐。这样可以避免在像B这样的大矩阵上进行转置,尽管由于您将三次运算作为主要步骤,所以这对您的问题无关紧要。
  • 根据是否需要原始数据以及所涉及的矩阵是否具有其他特殊属性,您可以可能摆弄scipy.linalg.solve中的参数以获取收益。
  • 我成功地将大型矩阵方程式替换为基于numpy例程的块矩阵方程式。与numpy方法相比,该方法通常可节省5-20%,而在我的系统上,scipy方法可节省大约1%。我尚未完全探讨出现差异的原因。

答案 1 :(得分:1)

假设矩阵稀疏,则scipy.sparse.linalg模块将非常有用。 Here是整个模块的文档,而herespsolve的文档。