_squared_euclidean函数详解:计算两个样本集中两两样本(来自不同样本集)之间的距离

看GLVQ的代码时候,发现下面一段(已经被我拆分了,方便调试),本来不知所云,后来发现,里面文章大得很。

def _squared_euclidean(a, b=None):
    if b is None:
        d = np.sum(a ** 2, 1)[np.newaxis].T + np.sum(a ** 2, 1) - 2 * a.dot(
            a.T)
    else:
        d = np.sum(a ** 2, 1)[np.newaxis].T
        e = np.sum(b ** 2, 1)
        f = d + e
        g = 2 * a.dot(b.T)
        h = f - g
    return np.maximum(h, 0), d, d.shape, e, e.shape, f, f.shape, g, g.shape


a = np.array([[1, 2], [3, 4]])
b = np.array([[2, 3], [4, 1]])
c = _squared_euclidean(a, b)
print(c)

结果为:

C:\anconda3\python.exe C:/hellopytorch/mel_ceshi.py
(array([[ 2, 10],
       [ 2, 10]]), array([[ 5],
       [25]], dtype=int32), (2, 1), array([13, 17], dtype=int32), (2,), array([[18, 22],
       [38, 42]], dtype=int32), (2, 2), array([[16, 12],
       [36, 32]]), (2, 2))

Process finished with exit code 0

比较d,e的形状,我发现了[np.newaxis].T的作用:d本来应该是e的形状,也就是(2,),应该是一个一维的数组,当然只是一行;经过[np.newaxis]之后,增加了一个维度,也就是在最外面加了一对[],形状变为(1, 2),虽然变成了二维数组,依然是一行;紧接着进行了转置.T,形状变成了(2, 1),就变成了最终的形式[[ 5], [25]]
还有很重要的一点是,d + e时候,他们的形状本来是不同的,numpy这个模块中,实现了低维的轴扩展成高维的轴再相加,其实是实现了[[5, 5], [25, 25]] + [[13, 17], [13, 17]],最后的结果就是[[18, 22], [38, 42]]
其实,这个函数想实现的就是两个样本点之间的距离平方和。比如这里就是a, b所包含的两个样本之间的距离,这里各有两个样本,所以产生了四个距离,只不过这里巧了,其中存在距离是一样的。h中第一行表示 a中第一个样点(第一行表示的样本点)与b中第一个和第二个样本点之间的距离。第二行以此类推。
从中get到的一点心得就是,比较复杂的公式,拆成一段一段去分析,化繁为简,或许能有好结果。

你可能感兴趣的:(_squared_euclidean函数详解:计算两个样本集中两两样本(来自不同样本集)之间的距离)