Взаимная корреляция/подобие сигналов - расчет временной задержки

У меня есть два сигнала, которые я хочу сравнить с точки зрения сходства. Один меньше (по времени), чем другой. Если я использую корреляцию, чтобы найти наибольшее сходство, это говорит мне, что самые высокие значения имеют значение, при котором я этого не ожидал.

Может ли кто-нибудь дать мне подсказку, если я просто думаю «неправильно», или корреляция - неправильный инструмент для такого рода проблем?

Моя установка:

import numpy
import matplotlib.pyplot as plt

signal_a = numpy.array([10, 20, 10, 30, 20, 10, 28, 22, 10])
signal_b = numpy.array([28, 22])
correlations = numpy.correlate(signal_a, signal_b, mode = "full")

print(correlations)
plt.plot(correlations)

Выводит эту диаграмму и массив корреляций

Наивысшая корреляция [28, 22] рассчитана в позиции [..., 30, 20, ...]. Я понимаю формулу и почему это 1280. Но на самом деле я ищу [..., 28, 22, ...], поскольку это именно (в данном случае) то, что я ищу (Сигнал B).

Правильно ли делать корреляцию? Я нашел так много источников, где используется корреляция для обнаружения сходства. Разве одни и те же значения не должны быть более похожими, чем любые другие?


person dest    schedule 14.11.2018    source источник


Ответы (2)


Одним из возможных решений вашей проблемы является среднеквадратичная ошибка (MSE). Учитывая два сигнала a и b одинаковой размерности, MSE представляет собой среднее значение поэлементных квадратов разницы между a и b. Код будет выглядеть следующим образом (на основе этого):

import numpy as np
import matplotlib.pyplot as plt

a = np.array([10, 20, 10, 30, 20, 10, 28, 22, 10])
b = np.array([28, 22])
mse = np.ndarray((len(a) - len(b) + 1))

for i in range(c.size):
    mse[i] = np.square(np.subtract(a[i:i+len(b)],b)).mean()

print(mse.argmin())
plt.plot(mse)
person mahesh    schedule 14.11.2018
comment
Спасибо, что направили меня к другому возможному решению. Мы попробуем это решение, но знаете ли вы, почему перекрестная корреляция неверна для нашей проблемы? - person dest; 21.11.2018
comment
@dest : Потому что numpy.correlate на самом деле не вычисляет взаимную корреляцию, как ее понимают статистики. Для этого вам нужно использовать numpy.corrcoef (документы. scipy.org/doc/numpy-1.15.0/reference/generated/). Но этой функции, кажется, нужны еще некоторые параметры, которые я на самом деле не исследовал. Вы также можете использовать этот метод, если хотите. Для большинства целей MSE достаточно хорош. - person mahesh; 21.11.2018

Вместо того, чтобы изучать корреляцию, вы можете изучить разницу в значениях, чтобы обнаружить сходство. Например, вы можете выбрать каждые 2 элемента в a (если b имеет длину 2) и посмотреть на абсолютные значения различий:

 import numpy as np
 import matplotlib.pyplot as plt

 signal_a = np.array([10, 20, 10, 30, 20, 10, 28, 22, 10])
 signal_b = np.array([28, 22])
 N2 = len(signal_b)

 diffs = []
 for i in range(len(signal_a) - len(signal_b) + 1):
      diff_ab = signal_a[i:i+N2] - signal_b
      diffs.append(sum(abs(diff_ab)))

 print(diffs)
 plt.plot(diffs)

И найти минимум в массиве diffs. Вместо abs() вы также можете использовать квадратное значение разницы.

person Joris Spikker    schedule 14.11.2018