测量两个不规则图之间的相似性

pra*_*ln4 6 python signal-processing matplotlib correlation cross-correlation

我有两条不规则的线作为 [x,y] 坐标列表,其中有波峰和波谷。列表的长度可能略有不同(不相等)。我想测量它们的相似性,以便检查峰和谷(具有相似的深度或高度)是否以适当的间隔出现并给出相似性度量。我想在 Python 中做到这一点。是否有任何内置功能可以做到这一点?

在此处输入图片说明 在此处输入图片说明

Cha*_*kel 10

我不知道 Python 中有任何内置函数可以做到这一点。

我可以给你一个你可以使用的 Python 生态系统中可能的函数列表。这绝不是一个完整的函数列表,可能有很多我不知道的方法。

如果数据已排序,但您不知道哪个数据点是第一个,哪个数据点是最后一个:

  1. 使用有向 Hausdorff 距离

如果数据是有序的,并且您知道第一个和最后一个点是正确的:

  1. 离散 Fréchet 距离*
  2. 动态时间扭曲 (DTW) *
  3. 部分曲线映射 (PCM) **
  4. 曲线长度距离度量(使用从开始到结束的弧长距离)**
  5. 两条曲线之间的面积**

*一般用于各种机器学习任务的数学方法

**我用来识别独特材料滞后响应的方法

首先让我们假设我们有两个完全相同的随机 XY 数据。请注意,所有这些方法都将返回零。如果您没有,您可以从 pip 安装相似性度量。

import numpy as np
from scipy.spatial.distance import directed_hausdorff
import similaritymeasures
import matplotlib.pyplot as plt

# Generate random experimental data
np.random.seed(121)
x = np.random.random(100)
y = np.random.random(100)
P = np.array([x, y]).T

# Generate an exact copy of P, Q, which we will use to compare
Q = P.copy()

dh, ind1, ind2 = directed_hausdorff(P, Q)
df = similaritymeasures.frechet_dist(P, Q)
dtw, d = similaritymeasures.dtw(P, Q)
pcm = similaritymeasures.pcm(P, Q)
area = similaritymeasures.area_between_two_curves(P, Q)
cl = similaritymeasures.curve_length_measure(P, Q)

# all methods will return 0.0 when P and Q are the same
print(dh, df, dtw, pcm, cl, area)
Run Code Online (Sandbox Code Playgroud)

打印出来的输出是 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 这是因为曲线 P 和 Q 完全一样!

现在让我们假设 P 和 Q 不同。

# Generate random experimental data
np.random.seed(121)
x = np.random.random(100)
y = np.random.random(100)
P = np.array([x, y]).T

# Generate random Q
x = np.random.random(100)
y = np.random.random(100)
Q = np.array([x, y]).T

dh, ind1, ind2 = directed_hausdorff(P, Q)
df = similaritymeasures.frechet_dist(P, Q)
dtw, d = similaritymeasures.dtw(P, Q)
pcm = similaritymeasures.pcm(P, Q)
area = similaritymeasures.area_between_two_curves(P, Q)
cl = similaritymeasures.curve_length_measure(P, Q)

# all methods will return 0.0 when P and Q are the same
print(dh, df, dtw, pcm, cl, area)
Run Code Online (Sandbox Code Playgroud)

打印输出为 0.107、0.743、37.69、21.5、6.86、11.8,根据每种方法量化 P 与 Q 的差异。

您现在有许多方法可以比较两条曲线。我将从 DTW 开始,因为它已在许多时间序列应用程序中使用,这些应用程序看起来像您上传的数据。

我们可以使用以下代码可视化 P 和 Q 的样子。

plt.figure()
plt.plot(P[:, 0], P[:, 1])
plt.plot(Q[:, 0], Q[:, 1])
plt.show()
Run Code Online (Sandbox Code Playgroud)

XY 空间中的两条随机路径


Sha*_*wal 2

我不知道内置函数,但听起来你可以修改Levenshtein's distance。以下代码取自wikibooks上的代码。

def point_distance(p1, p2):
    # Define distance, if they are the same, then the distance should be 0


def levenshtein_point(l1, l2):
    if len(l1) < len(l2):
        return levenshtein(l2, l1)

    # len(l1) >= len(l2)
    if len(l2) == 0:
        return len(l1)

    previous_row = range(len(l2) + 1)
    for i, p1 in enumerate(l1):
        current_row = [i + 1]
        for j, p2 in enumerate(l2):
            print('{},{}'.format(p1, p2))
            insertions = previous_row[j + 1] + 1 # j+1 instead of j since previous_row and current_row are one character longer
            deletions = current_row[j] + 1       # than l2
            substitutions = previous_row[j] + point_distance(p1, p2)
            current_row.append(min(insertions, deletions, substitutions))
        previous_row = current_row

    return previous_row[-1]
Run Code Online (Sandbox Code Playgroud)