如何计算二维矩阵之间的距离

Posted

技术标签:

【中文标题】如何计算二维矩阵之间的距离【英文标题】:How to calculate distance between 2D matrices 【发布时间】:2016-10-30 18:02:29 【问题描述】:

社区,您好,

我是该网站的新成员(作为会员),所以如果您认为将其发布在http://datascience.stackexchange.com 上可能会更好,请告诉我。

我正在解决一个机器学习问题,该问题需要计算 NxM 维元素之间的距离,以实现某些分类算法。

元素的属性是一个二维矩阵(Matr),因此我正在寻找计算二维矩阵之间距离的最佳算法。 正如您将在下面看到的,“简单”的解决方案是将 2D 转换为 1D(矢量),然后实现任何距离算法,但我正在寻找更方便的方法(如果存在)。

到目前为止,我使用了以下方法:

    每个元素之间的欧式距离。

    import numpy as np
    def dist_euclidean(elem1, elem2):
        t_sum=0
        for i in range(len(elem1.Matr)):
            for j in range(len(elem1.Matr[0])):
                t_sum+= np.square(elem1.Matr[i][j]-elem2.Matr[i][j])
        return np.sqrt(t_sum)
    

    余弦相似度,我必须将 (NxM) 2D 矩阵转换为 (1xNM) 向量。

    from scipy.spatial import distance
    def dist_cosine(elem1, elem2):
        temp1=[]
        temp2=[]
        for i in range(len(elem1.Matr)):
            temp1.extend(elem1.Matr[i])
            temp2.extend(elem2.Matr[i])
        return distance.cosine(temp1, temp2)
    

    KL 散度(wiki),也发现只针对一维矩阵(Vector)的实现,因此做了以下转换:

    找到每个对应行之间的熵,然后对它们进行平均。

    import numpy as np
    from scipy.stats import entropy
    def dist_KL_row_avg(elem1, elem2):
        Y=[]
        for i in range(len(elem1.Matr)):
            Y.append(entropy(elem1.Matr[i], elem2.Matr[i]))
        return np.average(Y)
    

    通过附加行然后计算总熵将 (NxM) 2D 矩阵转换为 (1xNM) 向量。

    import numpy as np
    from scipy.stats import entropy
    def dist_KL_1d_total(elem1, elem2):
        temp1=[]
        temp2=[]
        for i in range(len(elem1.Matr)):
            temp1.extend(elem1.Matr[i])
            temp2.extend(elem2.Matr[i])
        return entropy(temp1, temp2)
    

    KS 测试 (wiki),也发现只有一维矩阵(向量)的实现,因此进行了与 KL 实现相同的转换:

    找到每个对应行之间的熵,然后对它们进行平均。

    import numpy as np
    from scipy.stats import ks_2samp
    def dist_KS_row_avg(elem1, elem2):
        Y=[]
        Z=[]
        for i in range(len(elem1.Matr)):
            Y.append(ks_2samp(elem1.Matr[i], elem2.Matr[i]))
        Z=[x[0]/x[1] for x in Y]
        return np.average(Z)
    

    通过附加行然后计算总熵将 (NxM) 2D 矩阵转换为 (1xNM) 向量。

    import numpy as np
    from scipy.stats import ks_2samp
    def dist_KS_1d_total(elem1, elem2):
        temp1=[]
        temp2=[]
        for i in range(len(elem1.Matr)):
            temp1.extend(elem1.Matr[i])
            temp2.extend(elem2.Matr[i])
        Y = ks_2samp(temp1, temp2)
        return Y[0]/Y[1]
    

以上所有方法都可以解决我的问题,但我很好奇,因为我找不到更具体的让我满意的东西。


编辑 1. 正如pltrdy 建议的那样,这里有一些关于这个问题的更多信息。

每个元素的初始数据是一系列代码 ex(C->B->D->B->A),然后将其转换为转换矩阵,该矩阵也针对每一行进行归一化。因此,我们矩阵中的每个单元格表示从代码 [i] 到代码 [j] 的转换概率。例如:

IN: A->C->B->B->A->C->C->A
OUT: 
    A     B     C
 A  0     0     1
 B  0.5   0.5   0
 C  0.33  0.33  0.33

考虑到这一点,最终目标是对不同的代码系列进行分类。该系列的长度不同,但由相同的代码制成。因此,转移概率矩阵在每种情况下都具有相同的维度。 我最初的问题是为了找到最合适的距离算法,这将产生最好的分类结果。

【问题讨论】:

您应该提供有关上下文/目标的更多信息。我的意思是,在我看来,如果不了解目标,就不可能提出一个好的距离函数。就像说“如果你有两点使用曼哈顿/欧几里得(等)距离”。我们可以回答在这种情况下使用的更一般的距离函数(例如,为您的 2D 点选择欧几里得),但这并不准确,可能不适合您的需要。 感谢您的建议,为了不让读者感到困惑,我一开始并没有发布太多信息。我希望编辑有所帮助,让我知道更多说明。 可以肯定的是,分类任务是从一系列代码中预测概率矩阵(我们例子中的out)?我不确定这是 - 严格来说 - 一项分类任务。我的意思是,我从来没有见过矩阵作为输出。 可能我不清楚,我会尽快编辑我的问题。分类任务是将代码系列分类到类中。因为它们不是固定长度的,所以我为每个矩阵制作了一个转移概率矩阵(一个系列中可能的代码对所有人来说都是相同的,比如说 10 个不同的代码),因为所有矩阵都将具有相同的大小(10x10)它更容易比较它们。因此,我正在寻找矩阵之间的距离。 老实说,我会选择 2,看起来不错,但不知道可以从更好的解决方案中得到什么。我猜余弦会明显优于欧几里得,不是吗?这个问题很有趣,但我想我会尝试一下:/(你看过马尔科夫链吗?考虑一下你的问题有点像马尔科夫) 【参考方案1】:

给定两个不同的转移矩阵AB和一个概率分布x作为行向量,根据A一步后的分布是xA,一步后的分布根据BxB。您可以在所有x 之间采用(两倍)最大统计距离

numpy.linalg.norm(A - B, numpy.inf)

【讨论】:

以上是关于如何计算二维矩阵之间的距离的主要内容,如果未能解决你的问题,请参考以下文章

Python (3) 如何计算欧式距离

二维卷积作为矩阵-矩阵乘法[关闭]

如何计算二维的所有成对距离

利用matlab对二维矩阵进行计算分析

1091.二维矩阵中的最短路径

matlab中如何计算二维数组大小?