Python 计算吸收马尔可夫链基本矩阵的最佳方法?

Python 计算吸收马尔可夫链基本矩阵的最佳方法?,python,algorithm,math,sparse-matrix,markov-chains,Python,Algorithm,Math,Sparse Matrix,Markov Chains,我有一个非常大的吸收马尔可夫链(从10个状态扩展到数百万个问题),非常稀疏(大多数状态只能对4或5个其他状态做出反应) 我需要计算这个链的一行基本矩阵(给定一个起始状态的每个状态的平均频率) 通常,我会通过计算(I-Q)^(-1)来实现这一点,但我还没有找到一个实现稀疏矩阵求逆算法的好库!我看过几篇关于它的论文,大部分都是P.h.D.级别的作品 我在谷歌上的大部分搜索结果都指向了一些帖子,这些帖子讨论了在求解线性(或非线性)方程组时不应该使用矩阵求逆。。。我不觉得这特别有用。基本矩阵的计算是否类

我有一个非常大的吸收马尔可夫链(从10个状态扩展到数百万个问题),非常稀疏(大多数状态只能对4或5个其他状态做出反应)

我需要计算这个链的一行基本矩阵(给定一个起始状态的每个状态的平均频率)

通常,我会通过计算
(I-Q)^(-1)
来实现这一点,但我还没有找到一个实现稀疏矩阵求逆算法的好库!我看过几篇关于它的论文,大部分都是P.h.D.级别的作品

我在谷歌上的大部分搜索结果都指向了一些帖子,这些帖子讨论了在求解线性(或非线性)方程组时不应该使用矩阵求逆。。。我不觉得这特别有用。基本矩阵的计算是否类似于求解方程组,而我只是不知道如何用另一个的形式来表示

因此,我提出两个具体问题:

计算稀疏矩阵逆矩阵的一行(或所有行)的最佳方法是什么?

计算大型吸收马尔可夫链基本矩阵行的最佳方法是什么?

Python解决方案会很好(因为我的项目目前仍然是一个概念验证),但是如果我必须用一些好的ol'Fortran或C语言来完成我的工作,这不是问题


编辑:我刚刚意识到矩阵A的逆B可以定义为AB=I,其中I是单位矩阵。这可能允许我使用一些标准的稀疏矩阵解算器来计算逆矩阵。。。我得走了,请随意完成我的思路,我开始认为这可能只需要一个真正的初等矩阵属性…

你得到建议不要使用矩阵逆解方程的原因是数值稳定性。当矩阵的特征值为零或接近零时,就会出现问题,要么是缺少逆矩阵(如果为零),要么是数值稳定性问题(如果接近零)。因此,解决这个问题的方法是使用一种不需要求逆的算法。解决办法是使用。这并没有提供一个完整的倒数,而是让你得到一个行梯队形式,一个上三角形式的推广。如果矩阵是可逆的,则结果矩阵的最后一行包含一行逆矩阵。因此,只需安排消除的最后一行是您想要的行


我将把它留给你们去理解为什么I-Q总是可逆的。

假设你们要做的是计算出,维基百科上重现的“有限马尔可夫链”(Kemeny和Snell)的方程是:

或者扩展基本矩阵

重新安排:

这是使用函数求解线性方程组的标准格式

将这一点付诸实践,以证明性能上的差异(即使对于比您描述的更小的系统也是如此)

介绍计算预期步骤数的两种备选方法

def expected_steps_fundamental(Q):
    I = numpy.identity(Q.shape[0])
    N = numpy.linalg.inv(I - Q)
    o = numpy.ones(Q.shape[0])
    numpy.dot(N,o)

def expected_steps_fast(Q):
    I = numpy.identity(Q.shape[0])
    o = numpy.ones(Q.shape[0])
    numpy.linalg.solve(I-Q, o)
选择一个足够大的示例,演示计算基本矩阵时出现的问题类型:

P = example(2000)
# drop the absorbing state
Q = P[:-1,:-1]
生成以下计时:

%timeit expected_steps_fundamental(Q)
1 loops, best of 3: 7.27 s per loop
以及:

还需要进一步的实验来测试稀疏矩阵的性能影响,但很明显,计算逆矩阵的速度要比您预期的慢得多


与这里介绍的方法类似的方法也可用于步骤数的变化

如果您需要Python解决方案,请将其标记为
Python
。还有其他的堆栈交换可能或多或少也有用。我正在研究PGM的一些东西,想知道是否有一种方法可以计算出这个值——不过不知道稀疏矩阵,祝你好运!
%timeit expected_steps_fundamental(Q)
1 loops, best of 3: 7.27 s per loop
%timeit expected_steps_fast(Q)
10 loops, best of 3: 83.6 ms per loop