Bunu , mgcv paketindeki mono.con()
ve pcls()
işlevleri aracılığıyla monotonite kısıtlamaları olan cezalandırılmış spline'ları kullanarak yapabilirsiniz . Yapılması gereken biraz uğraşma var, çünkü bu işlevler kullanıcı dostu değil , ancak adımlar, verdiğiniz örnek verilere uyacak şekilde değiştirilmiş, çoğunlukla örneğe dayanarak aşağıda gösterilmiştir :gam()
?pcls
df <- data.frame(x=1:10, y=c(100,41,22,10,6,7,2,1,3,1))
## Set up the size of the basis functions/number of knots
k <- 5
## This fits the unconstrained model but gets us smoothness parameters that
## that we will need later
unc <- gam(y ~ s(x, k = k, bs = "cr"), data = df)
## This creates the cubic spline basis functions of `x`
## It returns an object containing the penalty matrix for the spline
## among other things; see ?smooth.construct for description of each
## element in the returned object
sm <- smoothCon(s(x, k = k, bs = "cr"), df, knots = NULL)[[1]]
## This gets the constraint matrix and constraint vector that imposes
## linear constraints to enforce montonicity on a cubic regression spline
## the key thing you need to change is `up`.
## `up = TRUE` == increasing function
## `up = FALSE` == decreasing function (as per your example)
## `xp` is a vector of knot locations that we get back from smoothCon
F <- mono.con(sm$xp, up = FALSE) # get constraints: up = FALSE == Decreasing constraint!
Şimdi pcls()
sığdırmak istediğimiz cezalandırılmış kısıtlanmış modelin ayrıntılarını içeren nesneyi doldurmamız gerekiyor
## Fill in G, the object pcsl needs to fit; this is just what `pcls` says it needs:
## X is the model matrix (of the basis functions)
## C is the identifiability constraints - no constraints needed here
## for the single smooth
## sp are the smoothness parameters from the unconstrained GAM
## p/xp are the knot locations again, but negated for a decreasing function
## y is the response data
## w are weights and this is fancy code for a vector of 1s of length(y)
G <- list(X = sm$X, C = matrix(0,0,0), sp = unc$sp,
p = -sm$xp, # note the - here! This is for decreasing fits!
y = df$y,
w = df$y*0+1)
G$Ain <- F$A # the monotonicity constraint matrix
G$bin <- F$b # the monotonicity constraint vector, both from mono.con
G$S <- sm$S # the penalty matrix for the cubic spline
G$off <- 0 # location of offsets in the penalty matrix
Şimdi nihayet montajı yapabiliriz
## Do the constrained fit
p <- pcls(G) # fit spline (using s.p. from unconstrained fit)
p
spline karşılık gelen temel fonksiyonlar için bir katsayı vektörü içerir. Takılan spline'ı görselleştirmek için, modelden x aralığında 100 konumda tahmin edebiliriz. Arsada güzel bir düzgün çizgi elde etmek için 100 değer yapıyoruz.
## predict at 100 locations over range of x - get a smooth line on the plot
newx <- with(df, data.frame(x = seq(min(x), max(x), length = 100)))
Kullandığımız tahmin edilen değerleri üretmek için Predict.matrix()
, bir katsayı ile katsayıların p
takılan modelden tahmin edilen değerler vereceği şekilde bir matris üretir :
fv <- Predict.matrix(sm, newx) %*% p
newx <- transform(newx, yhat = fv[,1])
plot(y ~ x, data = df, pch = 16)
lines(yhat ~ x, data = newx, col = "red")
Bu aşağıdakileri üretir:
Verileri ggplot ile çizmek için düzenli bir forma sokmak size bırakacağım ...
Temel işlevinin boyutunu artırarak daha yakın bir oturmayı zorlayabilirsiniz (daha pürüzsüz olanın ilk veri noktasına uymasıyla ilgili sorunuzu kısmen yanıtlamak için) x
. Örneğin, k
eşittir 8
( k <- 8
) ve yukarıdaki kodu yeniden
Sen itemezsiniz k
bu veriler için çok daha yüksek ve uydurma üzerinde yaklaşık dikkatli olmak zorunda; tek pcls()
şey kısıtlamalar ve verilen temel işlevler göz önüne alındığında cezalandırılmış en küçük kareler sorununu çözmek, sizin için pürüzsüzlük seçimi yapmıyor - bilmiyorum ...)
İnterpolasyon istiyorsanız ?splinefun
, Hermite spline'larına ve monotoniklik kısıtlamalarına sahip kübik splinelara sahip temel R fonksiyonuna bakın . Ancak bu durumda veriler kesinlikle monotonik olmadığından kullanamazsınız.
plot(y~x,data=df); f=fitted( glm( y~ns(x,df=4), data=df,family=quasipoisson)); lines(df$x,f)