Eu tenho alguns dados que gostaria de suavizar para que os pontos suavizados diminuam monotonicamente. Meus dados diminuem acentuadamente e depois começam a se espalhar. Aqui está um exemplo usando R
df <- data.frame(x=1:10, y=c(100,41,22,10,6,7,2,1,3,1))
ggplot(df, aes(x=x, y=y))+geom_line()
O que é uma boa técnica de suavização que eu poderia usar? Além disso, seria bom poder forçar o 1º ponto suavizado a ficar próximo ao ponto observado.
regression
smoothing
Ben
fonte
fonte
plot(y~x,data=df); f=fitted( glm( y~ns(x,df=4), data=df,family=quasipoisson)); lines(df$x,f)
Respostas:
Você pode fazer isso usando splines penalizados com restrições de monotonicidade através das funções
mono.con()
epcls()
no pacote mgcv . Há um pouco de brincadeira por fazer, porque essas funções não são tão amigáveis quanto as do usuáriogam()
, mas as etapas são mostradas abaixo, com base principalmente no exemplo de?pcls
, modificado para se adequar aos dados de amostra que você forneceu:Agora precisamos preencher o objeto que é passado para
pcls()
conter detalhes do modelo restrito penalizado que queremos ajustarAgora podemos finalmente fazer o encaixe
p
contém um vetor de coeficientes para as funções básicas correspondentes ao spline. Para visualizar o spline ajustado, podemos prever a partir do modelo em 100 locais no intervalo de x. Fazemos 100 valores para obter uma boa linha suave no gráfico.Para gerar valores previstos, usamos
Predict.matrix()
, que gera uma matriz que, quando múltiplos por coeficientes,p
produzem valores previstos a partir do modelo ajustado:Isso produz:
Vou deixar que você obtenha os dados em um formato organizado para plotar com o ggplot ...
Você pode forçar um ajuste mais próximo (para responder parcialmente à sua pergunta sobre como ajustar o mais suave no primeiro ponto de dados) aumentando a dimensão da função base de
x
. Por exemplo, definirk
igual a8
(k <- 8
) e executar novamente o código acima, obtemosVocê não pode aumentar
k
muito esses dados e precisa ter cuidado com o excesso de ajuste; tudo o que vocêpcls()
está fazendo é resolver o problema dos mínimos quadrados penalizados, dadas as restrições e as funções básicas fornecidas, não está executando a seleção de suavidade para você - não que eu saiba ...)Se você deseja interpolação, veja a função R básica
?splinefun
que possui splines Hermite e splines cúbicos com restrições de monotonicidade. Nesse caso, você não pode usá-lo, pois os dados não são estritamente monotônicos.fonte
splinefun
foi o meu pensamento inicial também (eu estou interpolando), masspline(x=df$x, y=df$y, n=nrow(df), method="monoH.FC")
espline(x=df$x, y=df$y, n=nrow(df), method="hyman")
ambos geram erros #?mono.con
tem mais detalhes sobre o método.splinefun
está levantando um erro; Acabei de perceber que você pode ajustar um spline monotônico que interpola dados que não são monotônicos. A observação emx = 6
é maiory
que as observações emx = 5
. Você apenas terá que ignorar essa parte da resposta :-)mono.con
retorna para um spline cúbico.?pcls
tem exemplos de splines de placa fina e modelos aditivos que são menos amigáveis que o anterior, mas que podem expor um pouco mais da matemática se você estiver familiarizado com a matemática para esses tipos de spline (eu também não sou familiar).O recente pacote de fraude de Natalya Pya e baseado no artigo "Modelos de aditivos com restrição de forma" de Pya & Wood (2015) pode tornar muito mais fácil parte do processo mencionado na excelente resposta de Gavin.
Existem várias funções bs que você pode usar - no exemplo acima, usei mpd para "P-spline decrescente monotônico", mas também possui funções que reforçam a convexidade ou concavidade, separadamente ou ao lado das restrições monotônicas.
fonte