# X is an m-by-n matrix (rows are examples, columns are dimensions)
# D is an m-by-m symmetric matrix of pairwise Euclidean distances
a = np.sum(X**2, axis=1)
D = np.sqrt((a + a[np.newaxis].T) - 2*np.dot(X, X.T))
def my_pdist_compact(X):
D = np.empty(shape=[0,0], dtype=X.dtype)
for i in range(X.shape[0]-1):
D = np.append(D, np.sqrt(np.sum((X[i,] - X[i+1:,])**2, axis=1)))
return D
相当于MATLAB代码:
function D = my_pdist_compact(X)
n = size(X,1);
D = cell(n-1,1);
for i=1:n-1
D{i} = sqrt(sum(bsxfun(@minus, X(i,:), X(i+1:end,:)).^2, 2));
end
D = vertcat(D{:});
end
scipy中的
pdist
是不同函数的集合-不存在一个对所有这些函数同时进行等效的方法。然而,每一个特定的距离,作为一个封闭的数学表达式,可以写在表中,然后进行编译。在以minkowski
p
范数距离(copy+pasteable)为例:注意,
^{pr2}$abs
调用内置的__abs__
,因此abs
也是一个函数。我们现在可以将其与pdist
进行比较:这就产生了
正如您所看到的,对应关系是存在的,但是函数
f_minkowski
稍微更通用,因为它比较两个可能不同数组的行。如果将同一数组作为输入传递两次,f_minkowski
返回一个矩阵,而pdist
返回一个没有冗余的列表。如果需要这种行为,也可以完全动态地实现,但我将坚持这里的一般情况。在但是,应该注意一种特殊化的可能性:在
p=2
的情况下,通过二项式公式计算变得更简单,这可以用来节省内存中宝贵的空间:而上面实现的一般Minkowski距离创建了一个3D数组(由于避免了for循环和累积求和),它是禁止的,取决于d
(和nX, nY
),对于p=2
我们可以写它只使用
O(nX * nY)
空间而不是O(nX * nY * d)
我们检查对应关系,这次是针对一般问题:屈服
我以前没有使用过Theano,但是这里有一个基于纯Numpy函数的解决方案(也许您可以将它转换为等效的Theano函数)。请注意,我在下面的表达式中使用了automaticbroadcasting,因此如果Theano不支持它,您可能需要显式重写它):
它基于这样一个事实:
||u-v||^2 = ||u||^2 + ||v||^2 - 2*u.v
。(我用MATLAB在我的previousanswers中展示了这一点)以下是与Scipy现有函数的比较:
^{pr2}$差异应该可以忽略不计,接近机器epsilon(
np.spacing(1)
):高温
编辑:
下面是另一个单循环实现:
相当于MATLAB代码:
这将返回紧凑形式的成对距离(对称矩阵的上三角部分)。这与
pdist
的输出相同。使用squareform
将其转换为完整矩阵。在我将把它留给您看看是否可以使用ano编写等价的loop(参见^{} )!在
相关问题 更多 >
编程相关推荐