J'ai quelques données que je voudrais lisser pour que les points lissés diminuent de façon monotone. Mes données diminuent fortement puis commencent à se stabiliser. Voici un exemple utilisant 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()
Quelle bonne technique de lissage pourrais-je utiliser? De plus, ce serait bien si je pouvais forcer le 1er point lissé à être proche de mon point observé.
plot(y~x,data=df); f=fitted( glm( y~ns(x,df=4), data=df,family=quasipoisson)); lines(df$x,f)
Réponses:
Vous pouvez le faire en utilisant des splines pénalisées avec des contraintes de monotonie via les fonctions
mono.con()
etpcls()
dans le package mgcv . Il y a un peu à faire car ces fonctions ne sont pas aussi conviviales quegam()
, mais les étapes sont indiquées ci-dessous, basées principalement sur l'exemple de?pcls
, modifiées pour s'adapter aux exemples de données que vous avez donnés:Maintenant, nous devons remplir l'objet qui est passé à
pcls()
contenant les détails du modèle contraint pénalisé que nous voulons adapterMaintenant, nous pouvons enfin faire le montage
p
contient un vecteur de coefficients pour les fonctions de base correspondant à la spline. Pour visualiser la spline ajustée, nous pouvons prédire à partir du modèle à 100 emplacements sur la plage de x. Nous faisons 100 valeurs afin d'obtenir une belle ligne lisse sur l'intrigue.Pour générer des valeurs prédites que nous utilisons
Predict.matrix()
, qui génère une matrice telle que lorsque plusieurs par coefficientsp
produisent des valeurs prédites à partir du modèle ajusté:Cela produit:
Je vous laisse le soin de mettre les données sous une forme ordonnée pour tracer avec ggplot ...
Vous pouvez forcer un ajustement plus étroit (pour répondre partiellement à votre question sur l'ajustement plus fluide du premier point de données) en augmentant la dimension de la fonction de base de
x
. Par exemple, en définissantk
égal à8
(k <- 8
) et en réexécutant le code ci-dessus, nous obtenonsVous ne pouvez pas pousser
k
beaucoup plus haut pour ces données, et vous devez faire attention au sur-ajustement; tout ce qu'ilpcls()
y a à faire est de résoudre le problème des moindres carrés pénalisés étant donné les contraintes et les fonctions de base fournies, il n'effectue pas de sélection de lissage pour vous - pas que je sache ...)Si vous voulez une interpolation, alors voyez la fonction R de base
?splinefun
qui a des splines Hermite et des splines cubiques avec des contraintes de monotonie. Dans ce cas, vous ne pouvez toutefois pas l'utiliser, car les données ne sont pas strictement monotones.la source
splinefun
était ma pensée initiale aussi (j'interpole) maisspline(x=df$x, y=df$y, n=nrow(df), method="monoH.FC")
et lesspline(x=df$x, y=df$y, n=nrow(df), method="hyman")
deux soulèvent des erreurs?mono.con
a plus de détails sur la méthode.splinefun
soulève une erreur; Je viens de réaliser que vous pouvez adapter une spline monotone qui interpole des données qui ne sont pas elles-mêmes monotones. L'observation àx = 6
est plus grandey
que les observations àx = 5
. Vous n'aurez qu'à ignorer cette partie de la réponse :-)mono.con
revient pour une spline cubique.?pcls
contient des exemples de splines à plaques minces et de modèles additifs qui sont moins conviviaux que ceux ci-dessus, mais qui pourraient exposer un peu plus les mathématiques si vous êtes familier avec les mathématiques de ces types de splines (je ne suis pas très familier moi-même).Le récent paquet d'arnaques de Natalya Pya et basé sur le document "Shape constrained additive models" de Pya & Wood (2015) peut faciliter une partie du processus mentionné dans l'excellente réponse de Gavin.
Il existe un certain nombre de fonctions bs que vous pouvez utiliser - dans ce qui précède, j'ai utilisé mpd pour "monotonique décroissante P-spline", mais il a également des fonctions qui imposent la convexité ou la concavité séparément ou à côté des contraintes monotones.
la source