Instructions and Examples for P-spline S-plus Code: ps( )
The ps() function can be used within the gam() function, just as the commonly used smoothing
splines s( ) and loess lo( ) terms. However the arguments for ps( ) differ:
“ps”
<- function(x, ps.intervals=NULL,
lambda=0, degree=3, order=3, ridge.adj=0.0001, ridge.inv=0.0001)
· x: regressor of interest
· ps.intervals: number of equally-spaced B-spline
intervals (knots=ps.int+2*degree+1)
· lambda: non-negative regularization parameter for difference penalty
· degree: degree of B-splines
· order: order of difference penalty (natural number, 0 is ridge penalty)
· ridge.adj, ridge.inv: small positive numbers to stabilize linear dependencies among B-splines bases.
References:
Eilers, P.H.C. and Marx, B.D. (2002). Generalized
linear additive smooth structures (GLASS). Journal of Computational and
Graphical Statistics 11(4): 758-783.
Marx,
B.D. and Eilers, P.H.C. (1998). Direct generalized additive modeling with
penalized likelihood. Computational
Statistics and Data Analysis 28(2): 193-209.
Eilers,
P.H.C. and Marx, B.D. (1996). Flexible smoothing with B-splines and penalties
(with comments and rejoinder). Statistical
Science 11(2): 89-121.
Some comments:
The spirit of P-splines
is to purposely overfit using a modest number (say 20) of equally spaced
B-spline bases. Further smoothness is ensured through a difference penalty on
adjacent B-spline coefficients. Optimal lambda can be found by minimizing AIC,
BIC or CV. The ps() function is
used directly in the gam() function.
Examples follow below. The plot.ps(), ps.wam(), gam.slist, and gam.wlist are
support functions for glass(). The use
of smooth ps() terms can
co-exist with linear (polynomial) or factor terms in a GAM. However ps() terms cannot co-exist with other s() or lo() terms in a GAM. The default of glass() is identical to ps().
Examples:
source('ps.code')
# GAM logistic
regression with 2 smooths and 1 linear and 1 block term
ps1 <- gam(binary.Y ~ ps(X1,
ps.int=10, lambda=1, degree=2, order=2) + X2
+ ps(X3, ps.int=20, varying.index=t.col, lambda=10)
+ factor(block), family=binomial)
names(ps1)
ps1$nl.dim
ps1$lin.dim
aic1 <- ps1$dev +
2*(sum(ps1$nl.dim)+sum(ps1$lin.dim))
aic1
plot.ps(ps1, type=’smooth’, index=1,
t.domain=X1)
plot.glass(glass1, type=’smooth’,
index=2, t.domain=X3)
# Univariate Smoother
using P-splines and a binomial response (same as ps( ))
pgam2 <- gam(Kyphosis ~ glass(Age, ps.int=20, lambda=.1, degree=4, order=4), family=binomial)
plot.ps(pgam2)