Recherche d'extrêmes locaux d'une fonction de densité à l'aide de splines

15

J'essaie de trouver les maxima locaux pour une fonction de densité de probabilité (trouvée en utilisant la densityméthode de R ). Je ne peux pas faire une simple méthode "regarder autour des voisins" (où l'on regarde autour d'un point pour voir s'il s'agit d'un maximum local par rapport à ses voisins) car il y a un grand volume de données. De plus, il semble plus efficace et générique d'utiliser quelque chose comme l'interpolation Spline et de trouver ensuite les racines de la dérivée première, au lieu de construire un "regard autour des voisins" avec une tolérance aux pannes et d'autres paramètres.

Alors, mes questions:

  1. Étant donné une fonction de splinefun, quelles méthodes trouveront les maxima locaux?
  2. Existe-t-il un moyen simple / standard de trouver les dérivés d'une fonction renvoyée à l'aide de splinefun?
  3. Existe-t-il un moyen meilleur / standard de trouver les maxima locaux d'une fonction de densité de probabilité?

Pour référence, ci-dessous est un tracé de ma fonction de densité. Les autres fonctions de densité avec lesquelles je travaille sont de forme similaire. Je dois dire que je suis nouveau dans R, mais pas nouveau dans la programmation, donc il peut y avoir une bibliothèque ou un package standard pour réaliser ce dont j'ai besoin. fonction de densité

Merci de votre aide!!

aaronlevin
la source
Je ne comprends pas pourquoi le grand volume de données est un problème pour la méthode du «regard autour des voisins». density()n'évalue pas la densité pour chaque donnée, il estime la densité à n valeurs, où n est un paramètre spécifié par l'utilisateur avec la valeur par défaut n = 512.
onestop
Mon n pour cela est 2 ^ 15 et il semble que les données aient beaucoup de variance au niveau point par point. J'ai essayé d'écrire un chercheur max / min en utilisant quelque chose de similaire à la méthode des quartiers (via msExtrema {msProcess}) et je n'ai pu identifier que quelques-uns des maximums, jamais tous, en jouant avec les paramètres de tolérance.
aaronlevin
2
En regardant le code msExtrema, c'est un simple wrapper pour peaksle splus2Rpackage, que vous feriez mieux d'utiliser directement si vous ne voulez que les maxima locaux et non les minima locaux. Je ne vois pas pourquoi l'utilisation de la valeur par défaut span=3ne trouverait pas tous les maxima locaux. Et 2 ^ 15 = 32768 ne devrait pas être assez grand pour que l'efficacité soit un gros problème.
onestop
La fonction retournée par splinefun a un argument "dérivé" qui est 0 par défaut. Définissez dérivé = 1 pour la première dérivée.
Cyan
1
Hmm, peakssemble être bogué: il appelle max.colavec le paramètre par défaut de ties.method = "random", qui non seulement rompt les liens au hasard, mais définit également une tolérance relative de 1e-5 pour déclarer une égalité. Le premier est déroutant, le second n'est certainement pas ce que vous voulez ici. peaks()prend également un strictparamètre mal documenté et, en regardant le code de la fonction, ne fait rien. Ah, les joies des bibliothèques de logiciels fournies par les utilisateurs! Vous pourriez bien être en mesure de le corriger si, comme vous dites que vous n'êtes pas nouveau à la programmation,
onestop

Réponses:

14

Ce que vous voulez faire, c'est la détection des pics en chimiométrie. Il existe différentes méthodes pour cela. Je ne démontre ici qu'une approche très simple.

require(graphics)
#some data
d <- density(faithful$eruptions, bw = "sj")

#make it a time series
ts_y<-ts(d$y)

#calculate turning points (extrema)
require(pastecs)
tp<-turnpoints(ts_y)
#plot
plot(d)
points(d$x[tp$tppos],d$y[tp$tppos],col="red")
Roland
la source
De toutes les solutions, cela a fonctionné le mieux. 1. Question de suivi: existe-t-il un moyen de basculer la tolérance avec les points de retournement? On a trouvé beaucoup de pics et de vallées dans la partie longue queue de la fonction de densité. 2. Question de suivi n ° 2: quelle est la bonne façon de déterminer la tolérance?
aaronlevin
annonce 1. Je ne pense pas. Il est destiné à tester le caractère aléatoire des séries chronologiques, de sorte que la fonction n'en a pas besoin. Vous pouvez essayer de tester vous-même la pertinence / signification d'un pic. Par exemple, vous pouvez faire un test t par rapport au quartier (où vous pouvez décider de la taille du quartier). Ou vous pouvez rechercher une fonction plus sophistiquée dans les packages R pour l'évaluation des données de la spectrométrie (de masse) ou d'autres méthodes de chimie analytique.
Roland