2015-10-07 2 views
2

При использовании xcorr в MATLAB для перекрестного сопоставления 2 связанных наборов данных все работает как ожидается - я вижу корреляционный пик и отмеченное сообщение о задержке. Однако, когда я использую xcorr для перекрестного сопоставления несвязанных наборов данных, где оба набора данных содержат 1 кластер «спайков», я вижу корреляционный пик, и зарегистрированное отставание - это расстояние между двумя шипами.Перекрестные корреляционные данные, содержащие «всплески»

В этом изображении:

image

x является случайной последовательности данных. y также представляет собой случайную серию данных. Оба x и y имеют 30 случайных пиков, вставленных в последовательность последовательно. Теоретически не должно быть никакой корреляции между двумя наборами данных, поскольку они оба очень разные. Однако из 3-го графика видно, что существует очень сильная корреляция между двумя наборами данных. Код, используемый для создания этой цифры, находится внизу этой публикации.

Я попытался отфильтровать шипы, используя несколько разных механизмов (скорость вращения rms и т. Д.) Перед выполнением xcorr. В некоторых случаях это работает, но не все. Я чувствую, что мне нужен другой подход к проблеме, возможно, альтернатива xcorr. Я понимаю, почему x и y перекрестный коррелятор с использованием xcorr. Есть ли другой инструмент взаимной коррекции, который я могу использовать? Примечание x и y никогда не будут точно такими же, они будут только когда-либо примерно такими же, но при нормальной работе это не шипы, которые должны заставить их коррелировать.

Любые предложения о том, как определить, соответствуют ли x и y корреляции, а также игнорируя «всплески»?

Вот некоторые мой пример кода:

x = rand(1, 3000); 
x = x - 0.5; 
y = rand(1, 3000); 
y = y - 0.5; 
% insert the impulses into the data 
impulse_width = 30; 
impulse_max_height = 6; 
x_impulse_start = 460; 
y_impulse_start = 120; 
rand_insert_x = rand(1, impulse_width); 
rand_insert_x = (rand_insert_x - 0.5) * 2 * impulse_max_height; 
rand_insert_y = rand(1, impulse_width); 
rand_insert_y = (rand_insert_y - 0.5) * 2 * impulse_max_height; 
x(1,x_impulse_start:x_impulse_start + impulse_width - 1) = rand_insert_x; 
y(1,y_impulse_start:y_impulse_start + impulse_width - 1) = rand_insert_y; 
subplot(3, 1, 1); 
plot(x); 
ylim([-impulse_max_height impulse_max_height]); 
title('random data series: x'); 
subplot(3, 1, 2); 
plot(y); 
ylim([-impulse_max_height impulse_max_height]); 
title('random data series: y'); 
[c, l] = xcorr(x, y); 
subplot(3, 1, 3); 
plot(l, c); 
title('correlation using xcorr'); 
+1

Я вижу, почему это проблема, но если бы я не читал ваше сообщение, я бы подумал: «xcorr» делает хорошую работу, так как он выравнивает эти очень похожие сигналы вместе! –

+0

Я думаю, первым шагом должно быть то, как вы определяете, считается ли «куча данных» всплеском или нет. – rst

ответ

0

Взаимная корреляция является convolution двух сигналов. Представьте, что во время взаимной корреляции, два сигнала находятся на запаздываний, как я показал здесь (х-метки оси должны быть полностью проигнорированы): enter image description here

положительный (+) шип в серии х (~ образца 490) является умноженное на отрицательный (-) всплеск в серии y (~ образец 121), что приводит к большому отрицательному значению в xcorr, которое мы фактически видим в нижнем графике (~ образец 315). Это большое отрицательное значение будет добавлено чем-то близким к 0, так как остальные сигналы действительно маломощные. Я боюсь, что независимо от того, какую функцию xcorr вы используете, вы должны получить тот же результат. На самом деле, если есть еще одна функция, которая утверждает, что она является кросс-коррелятором, но не дает того же результата, что и xcorr(), тогда эту функцию нельзя называть кросс-коррелятором. Надеюсь, это поможет.

1

Способ решения этой проблемы - использовать нормированную взаимную корреляцию.

При нормализации кросс-корреляции корреляция равна 1, когда сигналы одинаковы и меньше, если они не являются. Вы можете видеть это как «процент сходства».

Чтобы сделать это в MATLAB, вам просто нужно добавить 'coeff' в качестве аргумента в свой код.

Так что, если я изменить свой код, чтобы [c, l] = xcorr(x, y,'coeff'); сюжет я получаю это гнездо:

(обратите внимание, я изменил размер выборки до 600, чтобы сделать его более удобным для чтения)

enter image description here

крест -корреляция доходит до 0,3, так что не так много. Однако, если мы изменить код строки

x(1,x_impulse_start:x_impulse_start + impulse_width - 1) = rand_insert_x; 
y(1,y_impulse_start:y_impulse_start + impulse_width - 1) = rand_insert_x; 

и вставить ту же случайную скороговоркой в ​​обоих сигналов, то мы получим:

enter image description here

Теперь кросс-корреляции получает высокое значение , почти 1, но не один, потому что большой случайный шаблон там же, но остальная часть сигнала отсутствует.

+0

Спасибо за ответ Андер. – Mise

+0

@Mise Если это работает для вас, рассмотрите его как действительное: https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work –

0

Мое понимание вопроса: «Как удалить эти пики из моих данных?»

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

Например, вы можете сказать: «Спайк - это любая точка времени, которая имеет абсолютное значение, превышающее некоторый порог». Вы определяете порог, используя ваши данные, скажем 0.2. Тогда вы делаете что-то вроде

spikeless_data = data .* (abs(data)<0.2); 

, которая копирует данные, когда abs(data)<0.2 и устанавливает его в 0, когда нет.

Вы также можете заметить, что характеристикой шипов является то, что их производная очень велика, что может быть более надежным, чем простой порог. Это будет соответствовать spikeless_data = data .* ([abs(diff(data)), 0] < some_threshold);

Вам нужно будет поиграть, чтобы найти что-то, что работает для ваших данных.

Смежные вопросы