Localizando extremos locais de uma função de densidade usando splines

15

Estou tentando encontrar o máximo local para uma função de densidade de probabilidade (encontrada usando o densitymétodo de R ). Não consigo fazer um método simples de "olhar ao redor dos vizinhos" (onde se olha em torno de um ponto para ver se é um máximo local em relação aos vizinhos), pois há um grande volume de dados. Além disso, parece mais eficiente e genérico usar algo como a interpolação Spline e, em seguida, encontrar as raízes da 1ª derivada, em vez de criar um "olhar ao redor dos vizinhos" com tolerância a falhas e outros parâmetros.

Então, minhas perguntas:

  1. Dada uma função de splinefun, quais métodos encontrarão os máximos locais?
  2. Existe uma maneira fácil / padrão de encontrar derivadas de uma função retornada usando splinefun?
  3. Existe uma maneira melhor / padrão de encontrar os máximos locais de uma função de densidade de probabilidade?

Para referência, abaixo está um gráfico da minha função de densidade. Outras funções de densidade com as quais estou trabalhando são semelhantes em forma. Devo dizer que sou novo no R, mas não sou novo na programação; portanto, pode haver uma biblioteca ou pacote padrão para alcançar o que eu preciso. Função de densidade

Obrigado pela ajuda!!

aaronlevin
fonte
Não estou claro por que o grande volume de dados é um problema para o método de "olhar em torno dos vizinhos". density()não estimar a densidade para cada dado, estima a densidade a n valores, onde n é um parâmetro especificado pelo usuário com valor padrão n = 512.
Onestop
Meu n para isso é 2 ^ 15 e parece que os dados têm muita variação em um nível ponto a ponto. Tentei escrever um localizador de max / min usando algo semelhante ao método de vizinhanças (via msExtrema {msProcess}) e só consegui identificar alguns dos máximos, nunca todos, jogando com as configurações de tolerância.
precisa saber é o seguinte
2
Olhando para o código msExtrema, é um invólucro simples para peakso splus2Rpacote, que seria melhor usar diretamente se você quiser apenas o máximo local e não o mínimo local. Não vejo por que usar o padrão span=3não encontraria todos os máximos locais. E 2 ^ 15 = 32768 não deve ser grande o suficiente para que a eficiência seja uma grande preocupação.
onestop
A função retornada por splinefun possui um argumento "deriv" ​​que é 0 por padrão. Defina deriv = 1 para a primeira derivada.
Cyan
1
Hmm, peaksparece estar com erros: chama max.colcom a configuração padrão de ties.method = "random", que não apenas quebra os vínculos aleatoriamente, mas também define uma tolerância relativa de 1e-5 para declarar um empate. O primeiro é confuso, o último definitivamente não é o que você quer aqui. peaks()também pega um strictparâmetro mal documentado e, olhando o código da função, não faz nada. Ah, as alegrias das bibliotecas de software contribuídas pelos usuários! Você pode corrigi-lo, como diz que não é
iniciante em

Respostas:

14

O que você quer fazer é chamado de detecção de pico em quimiometria. Existem vários métodos que você pode usar para isso. Eu demonstro apenas uma abordagem muito simples aqui.

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
fonte
De todas as soluções, isso funcionou melhor. 1. Pergunta de acompanhamento: existe uma maneira de alternar tolerância com pontos de retorno? Encontrou muitos picos e vales na parte da cauda longa da função Densidade. 2. Pergunta de acompanhamento # 2: qual é uma boa maneira de determinar a tolerância?
aaronlevin
anúncio 1. Acho que não. Ele é destinado ao teste de aleatoriedade de séries temporais, para que a função não precise disso. Você pode tentar testar a relevância / significância de um pico. Por exemplo, você poderia fazer um teste t contra o bairro (onde você pode decidir qual o tamanho do bairro). Ou você pode procurar uma função mais sofisticada nos pacotes R para avaliação dos dados da espectrometria (de massa) ou de outros métodos de química analítica.
Roland