Voici mon expérience:
J'utilise la findPeaks
fonction dans le package quantmod :
Je veux détecter les pics "locaux" dans une tolérance de 5, c'est-à-dire les premiers emplacements après que la série chronologique ait chuté des pics locaux de 5:
aa=100:1
bb=sin(aa/3)
cc=aa*bb
plot(cc, type="l")
p=findPeaks(cc, 5)
points(p, cc[p])
p
La sortie est
[1] 3 22 41
Cela semble faux, car j'attends plus de "pics locaux" que 3 ...
Des pensées?
r
time-series
Luna
la source
la source
findPeaks
apparaît dans ma réponse, @Adam. BTW, le package est "quantmod" .Réponses:
La source de ce code est obtenue en tapant son nom à l'invite R. La sortie est
Le test
x[pks - 1] - x[pks] > thresh
compare chaque valeur de crête à la valeur qui lui succède immédiatement dans la série (et non au creux suivant de la série). Il utilise une estimation (brute) de la taille de la pente de la fonction immédiatement après le pic et ne sélectionne que les pics où cette pente dépassethresh
en taille. Dans votre cas, seuls les trois premiers pics sont suffisamment nets pour réussir le test. Vous détecterez tous les pics en utilisant la valeur par défaut:la source
Je suis d'accord avec la réponse de whuber, mais je voulais juste ajouter que la partie "+2" du code, qui tente de décaler l'index pour correspondre au pic nouvellement trouvé, "dépasse les limites" et devrait être "+1". par exemple dans l'exemple en question, nous obtenons:
lorsque nous mettons en évidence ces pics trouvés sur un graphique (rouge gras):
nous voyons qu'ils sont toujours à 1 point du pic réel.
conséquenty
devrait être
pks[x[pks] - x[pks + 1] > thresh]
oupks[x[pks] - x[pks - 1] > thresh]
GRANDE MISE À JOUR
suivant ma propre quête pour trouver une fonction de recherche de pic adéquate, j'ai écrit ceci:
un «pic» est défini comme un maximum local dont les
m
points de chaque côté sont plus petits que lui. par conséquent, plus le paramètre est grandm
, plus la procédure de financement de pointe est stricte. donc:la fonction peut également être utilisée pour trouver des minima locaux de tout vecteur séquentiel
x
viafind_peaks(-x)
.Remarque: j'ai maintenant mis la fonction sur gitHub si quelqu'un en a besoin: https://github.com/stas-g/findPeaks
la source
Eek: mise à jour mineure. J'ai dû changer deux lignes de code, les limites, (ajouter un -1 et +1) pour atteindre l'équivalence avec la fonction de Stas_G (il trouvait trop de «pics supplémentaires» dans les ensembles de données réels). Toutes mes excuses pour toute personne qui m'égare très légèrement par mon message d'origine.
J'utilise l'algorithme de recherche de pics de Stas_g depuis un certain temps maintenant. Cela m'a été bénéfique pour l'un de mes projets ultérieurs en raison de sa simplicité. Cependant, j'avais besoin de l'utiliser des millions de fois pour un calcul, je l'ai donc réécrit dans Rcpp (voir le paquet Rcpp). Il est environ 6 fois plus rapide que la version R dans des tests simples. Si quelqu'un est intéressé, j'ai ajouté le code ci-dessous. J'espère que j'aide quelqu'un, Cheers!
Quelques mises en garde mineures. Cette fonction renvoie les indices de crête dans l'ordre inverse du code R. Il nécessite une fonction de signe C ++ interne, que j'ai incluse. Il n'a pas été complètement optimisé mais aucun gain de performances supplémentaire n'est attendu.
la source
for(q = lb; q < rb; ++q){ if(vY(q) > vY(i+1)){ isGreatest = false; } }
comme la dernière course à travers la boucle « gagne », en faisant l'équivalent de:isGreatest = vY(rb-1) <= vY(rb)
. Pour obtenir ce que le commentaire juste au-dessus de cette ligne revendique, la boucle for devrait être remplacée par:for(q = lb; isGreatest && (q < rb); ++q){ isGreatest = (vY(q) <= vY(i+1)) }
Premièrement: l'algorithme appelle également faussement une baisse à droite d'un plateau plat car
sign(diff(x, na.pad = FALSE))
sera 0 puis -1 de sorte que son diff sera également -1. Une solution simple consiste à s'assurer que le signe-diff précédant l'entrée négative n'est pas nul mais positif:Deuxièmement: l'algorithme donne des résultats très locaux, par exemple un «haut» suivi d'un «bas» dans n'importe quelle série de trois termes consécutifs de la séquence. Si l'on s'intéresse plutôt aux maxima locaux d'une fonction continue bruyante, alors - il y a probablement d'autres choses meilleures là-bas, mais c'est ma solution bon marché et immédiate
lisser légèrement les données. Utilisez également le contrôle mentionné ci-dessus contre plat puis tombant.
filtrer ces candidats en comparant, pour une version lissée, la moyenne à l'intérieur d'une fenêtre centrée à chaque pic avec la moyenne des termes locaux à l'extérieur.
la source
Il est vrai que la fonction identifie également la fin des plateaux, mais je pense qu'il existe une autre solution plus simple: puisque le premier diff d'un vrai pic se traduira par «1» puis «-1», le deuxième diff serait «-2», et nous pouvons vérifier directement
la source
en utilisant Numpy
ou
en utilisant des pandas
la source