Python 随机转移概率矩阵的生成

Python 随机转移概率矩阵的生成,python,matrix,Python,Matrix,我想知道,在某些条件下,是否有一种简单的方法可以在python中生成填充随机数的方阵: 行的总和必须为1 对角线上的值应明显高于 其他价值观 这是一个随机矩阵,生成一个是可能的,然而棘手的部分是关于对角线的条件。 e、 g.对于4x4矩阵,输出应如下所示: [[0.90, 0.03, 0.03, 0.04], [0.01, 0.98, 0.005, 0.005], [0.04, 0.01, 0.92, 0.03], [0.00, 0.02, 0.03, 0.95]] 有没有好的方法可以为一

我想知道,在某些条件下,是否有一种简单的方法可以在python中生成填充随机数的方阵:

  • 行的总和必须为1
  • 对角线上的值应明显高于 其他价值观
这是一个随机矩阵,生成一个是可能的,然而棘手的部分是关于对角线的条件。 e、 g.对于4x4矩阵,输出应如下所示:

[[0.90, 0.03, 0.03, 0.04],
[0.01, 0.98, 0.005, 0.005],
[0.04, 0.01, 0.92, 0.03],
[0.00, 0.02, 0.03, 0.95]]

有没有好的方法可以为一个可变的大小生成这样的矩阵

这里有一个快速而肮脏的解决方案

import random

k = 4

result = [[random.uniform(0, 0.1 / k) for i in range(k)] for j in range(k)]
for j, r in enumerate(result):
    r[j] += 1 - sum(r)

你可能想考虑使用一个不同的随机分布,也可以看看NUMPY。

< P>这里有一个方法,用<代码> NUMPY。标识< /C> >,从k xk恒等式开始,向它添加一个漂移项,然后归一化。

import numpy as np

k = 4
result = np.identity(4)

# Add a random drift term.  We can guarantee that the diagonal terms
#     will be larger by specifying a `high` parameter that is < 1.
# How much larger depends on that term.  Here, it is 0.25.
result = result + np.random.uniform(low=0., high=.25, size=(k, k))

# Lastly, divide by row-wise sum to normalize to 1.
result = result / result.sum(axis=1, keepdims=1)

# Check
print(result)
print(result.sum(axis=1))

# [[ 0.80736896  0.00663004  0.06474194  0.12125906]
#  [ 0.03545472  0.79746194  0.10495657  0.06212678]
#  [ 0.08566011  0.02632533  0.79709851  0.09091605]
#  [ 0.07298408  0.05698381  0.1585878   0.71144431]]
#
# [ 1.  1.  1.  1.]
指定一个更大的
high
参数将使“对角线与其余对角线的比率”更小:


有多高?你有概率分布来量化吗?如果对角线上的所有值都高于0.90,我会很高兴!还没有用于量化的概率分布。Weeell,你可以对对角线值进行
随机.均匀(0.9,1.0)
,然后生成一个包含3个其他数字的列表,并简单地将它们归一化,使它们相加为
1-对角线值
。但我相信一些统计学家会指出这种方法是如何产生有偏差的数字样本的,所以你可能不想这样做。顺便说一下,如果你可以使用NUMPY,考虑添加标签。@ DutChJ,我无法想象一个情况下,我想要随机数,但甚至不关心分布是什么。你能为这个问题提供更多的背景吗?反过来说也行。首先使用具有适当小平均值的分布生成所有非对角条目,然后填写来自均匀分布的对角求和数将得到(低+高)/2=0.05的平均值。这意味着您的对角线将非常接近0.95。使用
np.array(result.diagonal()
来查看。你的矩阵越大,这就越明显。你是说它们不是很随机的?有人可能会认为,但是对角线元素的方差仍然是非对角线元素方差的(n-1)倍,所以我觉得这很好。对角线是随机的,但不是一致的。记住,它们受到其他数字总和的限制,你没有那种自由度。至于n个均匀数之和的分布,你看的是。对于极限n->无穷大,它是正态分布。所以这就像从分布N(0.95,σ)生成对角线一样。我最初建议的要点是对角线是统一选择的数字。由于其余的数字只是按比例缩小,它们仍然保持着均匀分布。这在我看来可能没什么问题,但我的直觉觉得这有点可疑,这就是为什么我把它作为一个建议。无论如何,OP对你的解决方案很满意。@43啊,我明白了。顺便说一句,我认为你的直觉是正确的。由于必须使用的比例因子取决于为该行绘制的所有数字,因此生成的条目不是独立的,也不是均匀分布的。我并不是说我的方法是OP问题的正确模型,但它在数学上更方便,主要是因为它避免了这些依赖关系。
result = np.identity(k) + np.random.uniform(low=0., high=.25, size=(k, k))
result /= result.sum(axis=1, keepdims=1)
result = np.identity(k) + np.random.uniform(low=0., high=.60, size=(k, k))
result /= result.sum(axis=1, keepdims=1)
print(result.round(2))
# [[ 0.53  0.02  0.25  0.2 ]
#  [ 0.05  0.58  0.19  0.18]
#  [ 0.02  0.04  0.72  0.22]
#  [ 0.07  0.23  0.08  0.62]]