Python 生成";“随机”;固定元素集上某一秩的矩阵
我想生成大小为Python 生成";“随机”;固定元素集上某一秩的矩阵,python,matlab,math,numpy,linear-algebra,Python,Matlab,Math,Numpy,Linear Algebra,我想生成大小为mxn和秩为r的矩阵,元素来自指定的有限集,例如{0,1}或{1,2,3,4,5}。我希望它们是“随机”的,在这个词的某个非常松散的意义上,也就是说,我希望从算法中获得各种可能的输出,其分布模糊地类似于所有矩阵在具有指定秩的元素集合上的分布 事实上,我并不关心它是否有秩r,只是它接近秩r(由Frobenius范数度量)的矩阵 当手头的集合是reals时,我已经做了以下工作,这完全满足了我的需要:生成大小为mxr和V的nxr的矩阵,并从中独立采样元素,例如Normal(0,2)。然后
m
xn
和秩为r
的矩阵,元素来自指定的有限集,例如{0,1}
或{1,2,3,4,5}
。我希望它们是“随机”的,在这个词的某个非常松散的意义上,也就是说,我希望从算法中获得各种可能的输出,其分布模糊地类似于所有矩阵在具有指定秩的元素集合上的分布
事实上,我并不关心它是否有秩r
,只是它接近秩r
(由Frobenius范数度量)的矩阵
当手头的集合是reals时,我已经做了以下工作,这完全满足了我的需要:生成大小为m
xr
和V
的n
xr
的矩阵,并从中独立采样元素,例如Normal(0,2)。然后uv'
是秩r
的m
xn
矩阵(好的,=r和n>=r)
反式=假
如果m>n:#我认为列多于行更好
m、 n=n,m
trans=真
get_vec=lambda:np.array([random.choice(VAL)表示范围(n)中的i)])
vecs=[]
n_拒绝=0
#填充r个线性独立的行
而len(vecs)len(vecs):
附加向量(v)
其他:
n_拒绝+=1
打印(“具有{}独立({}拒绝)”。格式(r,n_拒绝))
#填写其余的相关行
而len(vecs)len(vecs):
n_拒绝+=1
如果n_拒绝%1000==0:
打印(n_拒绝)
其他:
附加向量(v)
打印(“完成({}全部拒绝)”。格式(n_拒绝))
m=np.vstack(向量)
如果trans-else m,则返回m.T
这适用于任何秩的10x10二进制矩阵,但不适用于0-4个矩阵或秩较低的更大二进制矩阵(例如,获得秩15的20x20二进制矩阵需要42000次拒绝;使用秩10的20x20,需要120万次拒绝)
这显然是因为第一个r
行所跨越的空间在我采样的空间中太小了,例如在这些情况下,{0,1}^10
我们需要第一个r
行的跨度与有效值集的交点。
因此,我们可以尝试从范围中采样并寻找有效值,但由于范围涉及实值系数,因此永远无法找到有效向量(即使我们进行规范化,例如,第一个分量在有效集中)
也许这可以表述为一个整数规划问题,或者什么的?我的朋友丹尼尔·约翰逊(Daniel Johnson)在上面发表了评论,他提出了一个想法,但我看到他从未发布过。它不是很充实,但你可能能够适应它 如果
A
是m-by-r,B
是r-by-n,并且两者都有秩r,那么AB
有秩r。现在,我们只需要选择A
和B
,这样AB
只有给定集合中的值。最简单的情况是S={0,1,2,…,j}
一种选择是使用适当的行/列和生成一个二进制文件
这保证了正确的秩和B
,列和相加为no
超过j
(因此产品中的每个术语都是S
)和行总和
挑选以引起排名r
(或者至少鼓励它,因为可能会被拒绝
使用)
我只是觉得我们可以得出两个独立的样本
A
和B
上的方案比尝试更简单、更快速
一次攻击整个矩阵。不幸的是,我所有的矩阵
采样代码在另一台计算机上。我知道它很容易推广
允许输入大于{0,1}
(即S
)的项,但我不能
还记得计算是如何用m*n
缩放的吗
我不确定这个解决方案会有多有用,但你可以构造一个矩阵,允许你在另一个矩阵上搜索该解决方案,其中只有0和1作为条目。如果你在二进制矩阵上随机搜索,这相当于随机修改最终矩阵的元素,但也有可能想出一些规则这比随机搜索要好得多 如果要在元素集E和元素ei上生成
m
-by-n
矩阵,0这样如何
rank = 30
n1 = 100; n2 = 100
from sklearn.decomposition import NMF
model = NMF(n_components=rank, init='random', random_state=0)
U = model.fit_transform(np.random.randint(1, 5, size=(n1, n2)))
V = model.components_
M = np.around(U) @ np.around(V)
当你的矩阵是在有限集合上定义的,比如{0,1}
或{1,2,3,4,5}
你是否也在使用与这些集合上的向量空间一致的运算?如果不是,你将遇到问题。(例如,你必须对元素{0,1,2,3,4}进行算术mod 5)
获取该集合上的一组有效矩阵。您不能使用实值算术并期望随机抽取、线性组合等被关闭。)@很抱歉,我忘了提到我使用的是正规实向量空间。这就是我想要的:R上的矩阵,但其元素来自这些有限集。如果我做线性组合的事情,我显然必须小心这样做,元素仍然位于所讨论的集合中,但我希望秩w.R.t.实是r
。我认为你不能像那样混合和匹配基础字段。如果线性独立性的定义包括矩阵行/列中条目的实值系数,那么某些列的跨度可以是r上矩阵的巨大子集,而不是有限集上的矩阵。如果你处理matrIce必须在有限集上,然后你必须处理这个运算
def fill_matrix(m, n, r, vals):
assert m >= r and n >= r
trans = False
if m > n: # more columns than rows I think is better
m, n = n, m
trans = True
get_vec = lambda: np.array([random.choice(vals) for i in range(n)])
vecs = []
n_rejects = 0
# fill in r linearly independent rows
while len(vecs) < r:
v = get_vec()
if np.linalg.matrix_rank(np.vstack(vecs + [v])) > len(vecs):
vecs.append(v)
else:
n_rejects += 1
print("have {} independent ({} rejects)".format(r, n_rejects))
# fill in the rest of the dependent rows
while len(vecs) < m:
v = get_vec()
if np.linalg.matrix_rank(np.vstack(vecs + [v])) > len(vecs):
n_rejects += 1
if n_rejects % 1000 == 0:
print(n_rejects)
else:
vecs.append(v)
print("done ({} total rejects)".format(n_rejects))
m = np.vstack(vecs)
return m.T if trans else m
rank = 30
n1 = 100; n2 = 100
from sklearn.decomposition import NMF
model = NMF(n_components=rank, init='random', random_state=0)
U = model.fit_transform(np.random.randint(1, 5, size=(n1, n2)))
V = model.components_
M = np.around(U) @ np.around(V)