Вот мой эксперимент:
Я использую findPeaks
функцию в пакете quantmod :
Я хочу обнаружить «локальные» пики в пределах допуска 5, то есть первые местоположения после временного ряда падают с локальных пиков на 5:
aa=100:1
bb=sin(aa/3)
cc=aa*bb
plot(cc, type="l")
p=findPeaks(cc, 5)
points(p, cc[p])
p
Выход
[1] 3 22 41
Это кажется неправильным, так как я ожидаю больше "локальных пиков", чем 3 ...
Есть предположения?
r
time-series
Luna
источник
источник
findPeaks
появляется в моем ответе, @ Adam. Кстати, пакет "QuantMod" .Ответы:
Источник этого кода получается путем ввода его имени в приглашении R. Выход
Тест
x[pks - 1] - x[pks] > thresh
сравнивает каждое пиковое значение со значением, которое следует сразу за ним в серии (а не со следующим впадиной в серии). Он использует (грубую) оценку размера наклона функции сразу после пика и выбирает только те пики, где этот уклон превышаетthresh
размер. В вашем случае только первые три пика достаточно резкие, чтобы пройти тест. Вы обнаружите все пики, используя значение по умолчанию:источник
Я согласен с ответом whuber, но просто хотел добавить, что часть кода «+2», которая пытается сместить индекс, чтобы соответствовать вновь найденному пику, фактически «переходит» и должна быть «+1». например, в нашем примере мы получаем:
когда мы выделяем эти найденные пики на графике (жирный красный):
мы видим, что они последовательно 1 пункт от фактического пика.
consequenty
должно быть
pks[x[pks] - x[pks + 1] > thresh]
илиpks[x[pks] - x[pks - 1] > thresh]
БОЛЬШОЕ ОБНОВЛЕНИЕ
после моего собственного поиска, чтобы найти адекватную функцию поиска пика, я написал это:
«пик» определяется как локальные максимумы с
m
точками, каждая из сторон которых меньше его. следовательно, чем больше параметрm
, тем более строгой является процедура пикового финансирования. так:Функция также может быть использована для поиска локальных минимумов любого последовательного вектора
x
черезfind_peaks(-x)
.Примечание: теперь я поместил функцию на gitHub, если кому-то это нужно: https://github.com/stas-g/findPeaks
источник
Eek: Незначительное обновление. Мне пришлось изменить две строки кода, границы (добавить -1 и +1), чтобы достичь эквивалентности с функцией Stas_G (она находила слишком много «дополнительных пиков» в реальных наборах данных). Извинения за кого-то очень незначительно сбивают с толку моим оригинальным постом.
Я использую алгоритм поиска пиков Stas_g уже довольно давно. Это было выгодно для меня из-за его простоты. Однако мне нужно было использовать его миллионы раз для вычислений, поэтому я переписал его в Rcpp (см. Пакет Rcpp). Это примерно в 6 раз быстрее, чем версия R в простых тестах. Если кому-то интересно, я добавил код ниже. Надеюсь, я помогу кому-то, ура!
Некоторые незначительные предостережения. Эта функция возвращает пиковые индексы в обратном порядке кода R. Это требует встроенной функции C ++ Sign, которую я включил. Он не был полностью оптимизирован, но дальнейшего повышения производительности не ожидается.
источник
for(q = lb; q < rb; ++q){ if(vY(q) > vY(i+1)){ isGreatest = false; } }
в последнем прогоне через петлю «победу», делая эквивалент:isGreatest = vY(rb-1) <= vY(rb)
. Чтобы достичь того, о чем говорится в комментарии чуть выше этой строки, цикл for необходимо изменить на:for(q = lb; isGreatest && (q < rb); ++q){ isGreatest = (vY(q) <= vY(i+1)) }
Во-первых: алгоритм также ложно вызывает падение справа от плоского плато, так как
sign(diff(x, na.pad = FALSE))
будет 0, а затем -1, так что его разность также будет -1. Простое исправление состоит в том, чтобы гарантировать, что разность знаков, предшествующая отрицательной записи, не равна нулю, а положительна:Второе: алгоритм выдает очень локальные результаты, например, «вверх», за которым следует «вниз» при любом запуске трех последовательных членов в последовательности. Если вместо этого кто-то интересуется локальными максимумами зашумленной непрерывной функции, то - возможно, есть и другие лучшие вещи, но это мое дешевое и немедленное решение.
чтобы слегка сгладить данные. Также используйте вышеупомянутый контроль против квартиры, а затем падение.
отфильтруйте этих кандидатов, сравнив для сглаженной по Лессу версии среднее значение внутри окна, центрированного на каждом пике, со средним значением локальных членов снаружи.
источник
Это правда, что функция также идентифицирует конец плато, но я думаю, что есть другое более простое решение: так как первый дифференциал реального пика приведет к «1», а затем «-1», второй дифференциал будет «-2», и мы можем проверить напрямую
источник
используя Numpy
или
используя панд
источник