Pandas 用奇异值分解法求解欠定稀疏矩阵 问题

Pandas 用奇异值分解法求解欠定稀疏矩阵 问题,pandas,sparse-matrix,linear-algebra,svd,Pandas,Sparse Matrix,Linear Algebra,Svd,我有一组等式,变量用小写变量表示,常量用大写变量表示 A = a + b B = c + d C = a + b + c + d + e 我在一个包含两列的数据框架中获得了关于这些方程结构的信息:常量和变量 例如 然后使用NetworkX将其转换为稀疏CSC矩阵 table = nx.bipartite.biadjacency_matrix(nx.from_pandas_dataframe(df,'Constants','Variables') ,df.Constants.un

我有一组等式,变量用小写变量表示,常量用大写变量表示

A = a + b  
B = c + d  
C = a + b + c + d + e  
我在一个包含两列的数据框架中获得了关于这些方程结构的信息:常量变量

例如

然后使用NetworkX将其转换为稀疏CSC矩阵

table = nx.bipartite.biadjacency_matrix(nx.from_pandas_dataframe(df,'Constants','Variables')  
,df.Constants.unique(),df.Variables.unique(),format='csc')
当转换为密集矩阵时,表如下所示

矩阵([[1,1,0,0,0,0],[0,0,1,1,0],[1,1,1,1]],dtype=int64)

我想从这里找到哪些变量是可解的(在这个例子中,只有e是可解的),对于每个可解变量,它的值依赖于哪些常数(在这种情况下,由于e=C-B-A,它依赖于A、B和C)

试图解决问题 我首先尝试使用rref来求解可解变量。我使用了符号库sympy和函数sympy.Matrix.rref,这正是我想要的,因为任何可解变量都有自己的行,几乎所有的0和1,我可以逐行检查

然而,这种溶液并不稳定。首先,它非常慢,并且没有利用我的数据集可能非常稀疏这一事实。此外,rref在浮点运算方面做得不太好。因此,我决定转向另一种方法,该方法的动机是,建议使用svd

方便的是,scipy.sparse库中有一个svd函数,即scipy.sparse.linalg.svds。然而,鉴于我缺乏线性代数背景,我不理解在我的表上运行此函数所输出的结果,或者如何使用这些结果来获得我想要的结果

问题的进一步细节
  • 我的问题中每个变量的系数都是1。这就是如何在前面显示的两列数据框中表示数据
  • 在我的实际例子中,绝大多数变量都是不可解的。目标是找到少数几个可以解决的问题
  • 我非常愿意尝试另一种方法,如果它适合这个问题的约束条件

  • 这是我第一次发布问题,如果这不完全符合指导原则,我深表歉意。请留下建设性的批评,但要温柔

    您正在求解的系统具有以下形式

    [ 1 1 0 0 0 ] [a]   [A]
    [ 0 0 1 1 0 ] [b] = [B]
    [ 1 1 1 1 1 ] [c]   [C]
                  [d]
                  [e]
    
    i、 五个变量的三个方程
    a、b、c、d、e
    。正如你问题中的答案所提到的,你可以用Numpy直接提供的功能来解决这种不确定的系统

    由于
    M
    具有线性独立的行,因此在这种情况下,PSUDOVERSE具有
    M.pinv(M)=I
    的属性,其中
    I
    表示单位矩阵(在这种情况下为3x3)。因此,在形式上,我们可以将解决方案写成:

    v = pinv(M) . b
    
    其中,
    v
    是五组分溶液向量,
    b
    表示右侧三组分向量
    [A,b,C]
    。然而,该解决方案不是唯一的,因为可以从所谓的内核或矩阵
    M
    (即,向量
    w
    ,其中
    M.w=0
    )中添加向量,并且它仍然是一个解决方案:

    M.(v + w) = M.v + M.w = b + 0 = b
    
    因此,唯一存在唯一解决方案的变量是
    M
    零空间中所有可能向量的对应分量为零的变量。换句话说,如果将零空间的基组合成一个矩阵(每列一个基向量),那么“可解变量”将对应于该矩阵的零行(列的任何线性组合的相应分量也将为零)

    让我们将此应用于您的特定示例:

    import numpy as np
    from numpy.linalg import pinv
    
    M = [
        [1, 1, 0, 0, 0],
        [0, 0, 1, 1, 0],
        [1, 1, 1, 1, 1]
    ]
    
    print(pinv(M))
    
    [[ 5.00000000e-01 -2.01966890e-16  1.54302378e-16]
     [ 5.00000000e-01  1.48779676e-16 -2.10806254e-16]
     [-8.76351626e-17  5.00000000e-01  8.66819360e-17]
     [-2.60659800e-17  5.00000000e-01  3.43000417e-17]
     [-1.00000000e+00 -1.00000000e+00  1.00000000e+00]]
    
    从这个伪逆中,我们看到变量
    e
    (最后一行)确实可以表示为
    -A-B+C
    。然而,它也“预测”了
    a=a/2
    b=a/2
    。为了消除这些非唯一解(例如,同样有效的还有
    a=a
    b=0
    ),让我们计算借用SciPy函数的空空间:

    这个函数已经返回组装成矩阵的零空间的基(每列一个向量),我们可以看到,在合理的精度范围内,唯一的零行实际上只是对应于变量
    e
    的最后一行

    编辑:

    对于方程组

    A = a + b, B = b + c, C = a + c
    
    相应的矩阵
    M

    [ 1 1 0 ]
    [ 0 1 1 ]
    [ 1 0 1 ]
    
    这里我们看到矩阵实际上是平方的,并且是可逆的(行列式是
    2
    )。因此,伪逆与“正常”逆重合:


    它对应于解决方案
    a=(a-B+C)/2,…
    。因为
    M
    是可逆的,所以它的内核/null空间是空的,这就是为什么cookbook函数只返回
    []
    。为了了解这一点,让我们使用内核的定义-它由所有非零向量
    x
    构成,这样
    M.x=0
    。然而,由于存在
    M^{-1}
    ,因此
    x
    被给出为
    x=M^{-1}。0=0
    这是一个矛盾。形式上,这意味着找到的解决方案是唯一的(或者所有变量都是“可解的”)。

    要基于ewcz的答案,可以使用
    numpy.linalg.svd
    计算零空间和伪逆。请参阅以下链接:


    谢谢您的详细回复!我喜欢使用nullspace,但我有两个问题。首先,您知道在nullspace体中是否可以使用稀疏svd函数吗?我试图把它隐藏起来,但我没能弄明白。食谱中的零空间函数似乎也不适用于方程A=A+b,b=b+c,c=A+c的情况。我不想成为这里的吸血鬼帮手,但我真的不明白nullspace是怎么工作的。@RushabhMehta,我的荣幸!我没有详细研究稀疏版本,但只要它提供左/右奇异向量和
    A = a + b, B = b + c, C = a + c
    
    [ 1 1 0 ]
    [ 0 1 1 ]
    [ 1 0 1 ]
    
    [[ 0.5 -0.5  0.5]
     [ 0.5  0.5 -0.5]
     [-0.5  0.5  0.5]]