确定两个计数数组之间的相似性

Determine the similarity between two arrays of counts

问题: 我试图确定两个由计数组成的一维数组之间的相似性。数组内计数的位置相对大小都很重要。

X = [1, 5, 10, 0,  0, 0, 2]
Y = [1, 2,  0, 0, 10, 0, 5]
Z = [1, 3,  8, 0,  0, 0, 1]

在这种情况下,数组 X 比数组 Y 更类似于数组 Z。

我已经尝试了一些指标,包括 余弦距离、推土机距离和直方图交集,虽然余弦距离和推土机距离工作得很好,但只有 EMD 真正满足我的两个条件

我很想知道是否有其他算法/距离度量可以解决此类问题。

谢谢!

from dtaidistance import dtw
import numpy as np
X = [1, 5, 10, 0,  0, 0, 2]
Y = [1, 2,  0, 0, 10, 0, 5]
Z = [1, 3,  8, 0,  0, 0, 1]
def phase_corr(sig1, sig2):
    fft_sig1 = np.fft.fft(sig1)
    fft_sig2 = np.fft.fft(sig2)
    fft_sig2_conj = np.conj(fft_sig2)
    R = (fft_sig1 * fft_sig2_conj) / abs(fft_sig1 * fft_sig2_conj)
    r = np.fft.ifft(R)
    return np.real(r)

print(np.correlate(X, Z), np.correlate(Y, Z)) #cross-correlation
print(max(phase_corr(X, Z)), max(phase_corr(Y, Z))) 
print(dtw.distance(X, Z), dtw.distance(Y, Z)) #smaller distance means more similar
print(np.corrcoef(X, Z)[1,0], np.corrcoef(Y, Z)[1,0]) #Pearson correlation

一种流行且简单的方法是均方根,在这种方法中,您对元素之间的差值平方求和,取平方根,然后除以元素数,在您的例子中,X vs Y 产生2.1,X vs Z 产生 0.4。

import math

X = [1, 5, 10, 0,  0, 0, 2]
Y = [1, 2,  0, 0, 10, 0, 5]
Z = [1, 3,  8, 0,  0, 0, 1]

def rms(a,b):
    return math.sqrt( sum((a1-b1)*(a1-b1) for a1,b1 in zip(a,b)))/len(a)

print(rms(X,Y))
print(rms(X,Z))

也许曼哈顿距离适合你。 X和Y之间的曼哈顿距离是26,X和Z之间是5,Y和Z之间是23.

from math import sqrt
def manhattan(x, y):
    return sum(abs(val1-val2) for val1, val2 in zip(x,y))
X = [1, 5, 10, 0,  0, 0, 2]
Y = [1, 2,  0, 0, 10, 0, 5]
Z = [1, 3,  8, 0,  0, 0, 1]
manhattan(X, Y)  # returns 26
manhattan(X, Z)  # returns 5
manhattan(Y,Z)   # returns 23

查看 scipy.spatial.distance 了解各种距离指标。

例如,使用 Chebyshev distance,我们得到 X 与 Z 的相似度高于与 Y 的相似度。

from scipy.spatial import distance

X = [1, 5, 10, 0,  0, 0, 2]
Y = [1, 2,  0, 0, 10, 0, 5]
Z = [1, 3,  8, 0,  0, 0, 1]

print(distance.chebyshev(X, Y)) # returns 10
print(distance.chebyshev(X, Z)) # returns 2