Tengo algunos datos que me gustaría suavizar para que los puntos suavizados disminuyan monotónicamente. Mis datos disminuyen bruscamente y luego comienzan a estabilizarse. Aquí hay un ejemplo 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()
¿Cuál es una buena técnica de suavizado que podría usar? Además, sería bueno si puedo forzar el primer punto suavizado a estar cerca de mi punto observado.
plot(y~x,data=df); f=fitted( glm( y~ns(x,df=4), data=df,family=quasipoisson)); lines(df$x,f)
Respuestas:
Puede hacerlo utilizando splines penalizadas con restricciones de monotonicidad a través de las funciones
mono.con()
ypcls()
del paquete mgcv . Hay un poco de juego por hacer porque estas funciones no son tan fáciles de usargam()
, pero los pasos se muestran a continuación, basados principalmente en el ejemplo de?pcls
, modificado para adaptarse a los datos de muestra que proporcionó:Ahora necesitamos completar el objeto que se pasa a
pcls()
contener detalles del modelo restringido penalizado que queremos ajustarAhora finalmente podemos hacer el ajuste
p
contiene un vector de coeficientes para las funciones básicas correspondientes a la spline. Para visualizar la spline ajustada, podemos predecir a partir del modelo en 100 ubicaciones en el rango de x. Hacemos 100 valores para obtener una buena línea suave en la trama.Para generar valores pronosticados, utilizamos
Predict.matrix()
, que genera una matriz tal que cuando múltiples coeficientesp
rinden valores pronosticados del modelo ajustado:Esto produce:
Te lo dejaré a ti para obtener los datos en un formulario ordenado para trazar con ggplot ...
Puede forzar un ajuste más cercano (para responder parcialmente a su pregunta sobre cómo hacer que el ajuste más suave se ajuste al primer punto de datos) aumentando la dimensión de la función base de
x
. Por ejemplo, al establecerk
igual a8
(k <- 8
) y volver a ejecutar el código anterior, obtenemosNo puede presionar
k
mucho más por estos datos, y debe tener cuidado con el ajuste excesivo; todospcls()
está haciendo es resolver el problema de mínimos cuadrados penalizados dadas las restricciones y las funciones básicas proporcionadas, no está realizando una selección de suavidad para usted, no que yo sepa ...)Si desea la interpolación, vea la función base R
?splinefun
que tiene splines Hermite y splines cúbicas con restricciones de monotonía. Sin embargo, en este caso no puede usar esto ya que los datos no son estrictamente monótonos.fuente
splinefun
fue mi pensamiento inicial también (estoy interpolando) perospline(x=df$x, y=df$y, n=nrow(df), method="monoH.FC")
yspline(x=df$x, y=df$y, n=nrow(df), method="hyman")
ambos generan errores?mono.con
tiene más detalles sobre el método.splinefun
está generando un error; Me acabo de dar cuenta de que puedes ajustar una spline monotónica que interpola datos que no son en sí mismos monótonos. La observación enx = 6
es mayory
que las observaciones enx = 5
. Tendrás que ignorar esa parte de la respuesta :-)mono.con
devuelve una spline cúbica.?pcls
tiene ejemplos de splines de placa delgada y modelos aditivos que son menos fáciles de usar que los anteriores, pero que podrían exponer un poco más de las matemáticas si está familiarizado con las matemáticas para ese tipo de splines (yo tampoco estoy tan familiarizado).El reciente paquete de estafa de Natalya Pya y basado en el documento "Modelos de aditivos con restricciones de forma" de Pya & Wood (2015) puede hacer que parte del proceso mencionado en la excelente respuesta de Gavin sea mucho más fácil.
Hay una serie de funciones bs que puede utilizar: en el anterior utilicé mpd para "spline P decreciente monotónica", pero también tiene funciones que imponen convexidad o concavidad por separado o junto con las restricciones monotónicas.
fuente