【发布时间】:2015-08-04 03:22:45
【问题描述】:
编辑 2:这篇文章似乎已从 CrossValidated 移至 StackOverflow,因为它主要是关于编程的,但这意味着花哨的 MathJax 不再起作用了。希望这仍然是可读的。
假设我想用协方差矩阵 S 计算两个向量 x 和 y 之间的平方马氏距离。这是一个由
M2(x, y; S) = (x - y)^T * S^-1 * (x - y)
使用 python 的 numpy 包我可以这样做
# x, y = numpy.ndarray of shape (n,)
# s_inv = numpy.ndarray of shape (n, n)
diff = x - y
d2 = diff.T.dot(s_inv).dot(diff)
或在 R 中作为
diff <- x - y
d2 <- t(diff) %*% s_inv %*% diff
在我的情况下,我被给予了
-
mbyn矩阵X -
n-维向量mu -
nbyn协方差矩阵S
并且想找到m-维向量d这样
d_i = M2(x_i, mu; S) ( i = 1 .. m )
其中x_i 是X 的第i 行。
在python中使用一个简单的循环并不难完成:
d = numpy.zeros((m,))
for i in range(m):
diff = x[i,:] - mu
d[i] = diff.T.dot(s_inv).dot(diff)
当然,鉴于外部循环发生在 python 中,而不是 numpy 库中的本机代码中,这意味着它的速度不如预期的快。 $n$ 和 $m$ 分别约为 3-4 和几十万,我在交互式程序中经常这样做,因此加速会非常有用。
在数学上,我能够使用基本矩阵运算来表述这一点的唯一方法是
d = diag( X' * S^-1 * X'^T )
在哪里
x'_i = x_i - mu
这很容易编写一个矢量化版本,但不幸的是,计算一个超过 100 亿个元素的矩阵并且只取对角线的效率低下……我相信这个操作应该很容易用爱因斯坦表示法表达,因此希望可以使用numpy 的einsum 函数快速评估,但我什至还没有开始弄清楚这个黑魔法是如何工作的。
所以,我想知道:有没有更好的方法来数学地制定这个运算(就简单的矩阵运算而言),或者有人可以建议一些很好的矢量化(python 或 R)代码来有效地做到这一点?
奖励问题,勇敢者
我真的不想做一次,我想做k ~ 100 次。给定:
mbyn矩阵Xkbyn矩阵Un和n协方差矩阵的集合,每个矩阵都表示为S_j(j = 1..k)
通过k 矩阵D 找到m,这样
D_i,j = M(x_i, u_j; S_j)
其中i = 1..m、j = 1..k、x_i 是X 的第i 行,u_j 是j 的第U 行。
即,将以下代码矢量化:
# s_inv is (k x n x n) array containing "stacked" inverses
# of covariance matrices
d = numpy.zeros( (m, k) )
for j in range(k):
for i in range(m):
diff = x[i, :] - u[j, :]
d[i, j] = diff.T.dot(s_inv[j, :, :]).dot(diff)
【问题讨论】:
标签: r normal-distribution python matrix numpy