Алгоритм поиска пиков для Python / SciPy



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



мое конкретное приложение представляет собой 2D-массив, но обычно он будет использоваться для поиска пиков в БПФ и т. д.



в частности, в таких проблемах есть несколько сильных пиков, а затем много меньших "пиков", которые просто вызваны шумом, который должен быть игнорируемый. Это только примеры, не мои фактические данные:



1-мерных вершин:



FFT output with peaks



2-мерных вершин:



Radon transform output with circled peak



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



Как правило, вы только заботитесь около нескольких сильных пиков, поэтому они будут выбраны либо потому, что они выше определенного порога, либо потому, что они первые n пики упорядоченного списка, ранжированные по амплитуде.



Как я уже сказал, Я знаю, как писать что-то подобное сам. Я просто спрашиваю, есть ли уже существующая функция или пакет, который, как известно, хорошо работает.



обновление:



Я перевел сценарий MATLAB и он работает прилично для 1-D случай, но могло быть и лучше.



обновление:



sixtenbe создал лучшую версию для 1-го случая.

1699   8  

8 ответов:

Я не думаю, что то, что вы ищете, предоставляется SciPy. Я бы написал код сам, в этой ситуации.

сплайновая интерполяция и сглаживание от scipy.интерполировать довольно приятно и может быть весьма полезно при подгонке пиков, а затем найти местоположение их максимума.

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

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

в scipy есть функция с именем scipy.signal.find_peaks_cwt который звучит как подходит для ваших нужд, однако у меня нет опыта работы с ним, поэтому я не могу рекомендовать..

http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks_cwt.html

для тех, кто не уверен, какие алгоритмы поиска пиков использовать в Python, здесь Быстрый обзор альтернатив:https://github.com/MonsieurV/py-findpeaks

желая себе эквивалент в системе MATLAB

обнаружение пиков в спектре надежным способом было изучено совсем немного, например, все работы по синусоидальному моделированию для музыкальных/звуковых сигналов в 80-х годах. Ищите "синусоидальное моделирование" в литературе.

Если ваши сигналы так же чисты, как пример, простое "дайте мне что-то с амплитудой выше, чем N соседей" должно работать достаточно хорошо. Если у вас есть шумные сигналы, простой, но эффективный способ-смотреть на ваши пики во времени, отслеживать их: вы затем обнаруживают спектральные линии вместо спектральных пиков. IOW, вы вычисляете БПФ на скользящем окне вашего сигнала, чтобы получить набор спектра во времени (также называемый спектрограммой). Затем вы смотрите на эволюцию спектрального пика во времени (т. е. в последовательных окнах).

функции scipy.signal.find_peaks, как следует из названия, полезно для этого. Но важно хорошо понимать его параметры width,threshold,distanceи главное prominence получить хорошее пиковое извлечение.

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

что это (кадастровый) известность? Это "минимальная высота, необходимая для спуска с вершины на любую более высокую местность", как видно здесь:

enter image description here

идея:

чем выше протуберанец, тем более" важным " является пик.

тест:

enter image description here

я использовал (шумную) частотно-изменяющуюся синусоиду специально, потому что она показывает много трудностей. Мы видим, что width параметр здесь не очень полезен, потому что если вы установите минимум width слишком высоко, тогда он не сможет отслеживать очень близкие пики в высокочастотной части. Если вы установите width слишком низко, у вас будет много нежелательных пиков в левой части сигнала. Та же проблема с distance. threshold только сравнивает с прямыми соседями, что здесь не полезно. prominence - это тот, который дает лучшее решение. Обратите внимание, что вы можете объединить многие из вот эти параметры!

код:

import numpy as np
import matplotlib.pyplot as plt 
from scipy.signal import find_peaks, find_peaks_cwt

x = np.sin(2*np.pi*(2**np.linspace(2,10,1000))*np.arange(1000)/48000) + np.random.normal(0, 1, 1000) * 0.15
peaks, _ = find_peaks(x, distance=20)
peaks2, _ = find_peaks(x, prominence=1)      # BEST!
peaks3, _ = find_peaks(x, width=20)
peaks4, _ = find_peaks(x, threshold=0.4)     # Required vertical distance to its direct neighbouring samples, pretty useless
plt.subplot(2, 2, 1)
plt.plot(peaks, x[peaks], "xr"); plt.plot(x); plt.legend(['distance'])
plt.subplot(2, 2, 2)
plt.plot(peaks2, x[peaks2], "ob"); plt.plot(x); plt.legend(['prominence'])
plt.subplot(2, 2, 3)
plt.plot(peaks3, x[peaks3], "vg"); plt.plot(x); plt.legend(['width'])
plt.subplot(2, 2, 4)
plt.plot(peaks4, x[peaks4], "xk"); plt.plot(x); plt.legend(['threshold'])
plt.show()

существуют стандартные статистические функции и методы для поиска выбросов в данные, что, вероятно, то, что вам нужно в первом случае. Использование производных решит вашу вторую. Однако я не уверен в методе, который решает как непрерывные функции, так и выборочные данные.

во-первых, определение "пик" является расплывчатым, если без дополнительных спецификаций. Например, для следующей серии, вы бы назвали 5-4-5 один пик или два?

1-2-1-2-1-1-5-4-5-1-1-5-1

в этом случае вам понадобится по крайней мере два порога: 1) высокий порог, только выше которого экстремальное значение может регистрироваться как пик; и 2) низкий порог, так что экстремальные значения, разделенные небольшими значениями ниже него, станут двумя пиками.

пик обнаружение является хорошо изученной темой в литературе по теории экстремальных значений, также известной как"декластеризация экстремальных значений". Свои типичные применения включают определять случаи опасности основанные на непрерывных чтениях переменных окружающей среды например анализируя скорость ветра для того чтобы обнаружить случаи шторма.

Comments

    Ничего не найдено.