leverage.R
#
# leverage.R
#
# leverage and influence
#
# $Revision: 1.21 $ $Date: 2011/12/04 10:54:49 $
#
leverage <- function(model, ...) {
UseMethod("leverage")
}
leverage.ppm <- function(model, ...,
drop=FALSE, iScore=NULL, iHessian=NULL, iArgs=list())
{
fitname <- deparse(substitute(model))
u <- list(fit=model, fitname=fitname)
s <- ppm.influence(model, what="leverage", drop=drop,
iScore=iScore, iHessian=iHessian, iArgs=iArgs,
...)
a <- append(u, s)
class(a) <- "leverage.ppm"
return(a)
}
influence.ppm <- function(model, ...,
drop=FALSE, iScore=NULL, iHessian=NULL, iArgs=list())
{
fitname <- deparse(substitute(model))
u <- list(fit=model,fitname=fitname)
s <- ppm.influence(model, what="influence", drop=drop,
iScore=iScore, iHessian=iHessian, iArgs=iArgs,
...)
a <- append(u, s)
class(a) <- "influence.ppm"
return(a)
}
dfbetas.ppm <- function(model, ..., drop=FALSE, iScore=NULL, iHessian=NULL, iArgs=list()) {
fitname <- deparse(substitute(model))
u <- list(fit=model,fitname=fitname)
s <- ppm.influence(model, what="dfbetas", drop=drop,
iScore=iScore, iHessian=iHessian, iArgs=iArgs,
...)
a <- s$dfbetas
attr(a, "info") <- u
return(a)
}
ppm.influence <- function(fit,
what=c("leverage", "influence", "dfbetas", "derivatives"),
..., iScore=NULL, iHessian=NULL, iArgs=list(), drop=FALSE,
method=c("C", "interpreted")) {
stopifnot(is.ppm(fit))
# stopifnot(is.poisson.ppm(fit))
what <- match.arg(what)
method <- match.arg(method)
#
gotScore <- !is.null(iScore)
gotHess <- !is.null(iHessian)
needHess <- gotScore && any(what %in% c("leverage", "influence", "dfbetas"))
if(!gotHess && needHess)
stop("Must supply iHessian")
#
p <- length(coef(fit))
vc <- vcov(fit, hessian=TRUE)
fush <- hess <- solve(vc)
lam <- fitted(fit, check=FALSE)
mom <- model.matrix(fit)
Q <- quad.ppm(fit)
# hess = negative hessian of log (pseudo) likelihood
# fush = E(hess)
# invhess = solve(hess)
# vc = solve(fush)
#
w <- w.quad(Q)
loc <- union.quad(Q)
isdata <- is.data(Q)
#
if(length(w) != length(lam))
stop(paste("Internal error: length(w) = ", length(w),
"!=", length(lam), "= length(lam)\n"))
#
if(!is.null(iScore)) {
# evaluate additional (`irregular') components of score
iscoredf <- mpl.get.covariates(iScore, loc, covfunargs=iArgs)
iscoremat <- as.matrix(iscoredf)
# count regular and irregular parameters
nreg <- ncol(mom)
nirr <- ncol(iscoremat)
# add extra columns to model matrix
mom <- cbind(mom, iscoremat)
# evaluate additional (`irregular') entries of Hessian
if(gotHess) {
ihessdf <- mpl.get.covariates(iHessian, loc, covfunargs=iArgs)
ihessmat <- as.matrix(ihessdf)
}
# recompute negative Hessian of log PL and its mean
fush <- hessextra <- matrix(0, ncol(mom), ncol(mom))
sub <- nreg + 1:nirr
# integral over domain
switch(method,
interpreted = {
for(i in seq(loc$n)) {
# weight for integrand
wti <- lam[i] * w[i]
if(all(is.finite(wti))) {
# integral of outer product of score
momi <- mom[i, ]
v1 <- outer(momi, momi, "*") * wti
if(all(is.finite(v1)))
fush <- fush + v1
# integral of Hessian
# contributions nonzero for irregular parameters
if(gotHess) {
v2 <- matrix(as.numeric(ihessmat[i,]), nirr, nirr) * wti
if(all(is.finite(v2)))
hessextra[sub, sub] <- hessextra[sub, sub] + v2
}
}
}
# subtract sum over data points
if(gotHess) {
for(i in which(isdata)) {
v2 <- matrix(as.numeric(ihessmat[i,]), nirr, nirr)
if(all(is.finite(v2)))
hessextra[sub, sub] <- hessextra[sub, sub] - v2
}
hess <- fush + hessextra
invhess <- solve(hess)
} else {
invhess <- hess <- NULL
}
},
C = {
wlam <- lam * w
fush <- sumouter(mom, wlam)
if(gotHess) {
# integral term
ok <- is.finite(wlam) & apply(is.finite(ihessmat), 1, all)
vintegral <-
if(all(ok)) wlam %*% ihessmat else
wlam[ok] %*% ihessmat[ok,, drop=FALSE]
# sum over data points
vdata <- colSums(ihessmat[isdata, , drop=FALSE], na.rm=TRUE)
vcontrib <- vintegral - vdata
hessextra[sub, sub] <-
hessextra[sub, sub] + matrix(vcontrib, nirr, nirr)
hess <- fush + hessextra
invhess <- solve(hess)
} else {
invhess <- hess <- NULL
}
})
vc <- solve(fush)
}
if(!needHess) {
hess <- fush
invhess <- vc
}
#
if(drop) {
ok <- complete.cases(mom)
Q <- Q[ok]
mom <- mom[ok,]
loc <- loc[ok]
lam <- lam[ok]
w <- w[ok]
isdata <- isdata[ok]
}
#
result <- list()
if("derivatives" %in% what) {
rawresid <- isdata - lam * w
score <- matrix(rawresid, nrow=1) %*% mom
result$deriv <- list(mom=mom, score=score,
fush=fush, vc=vc,
hess=hess, invhess=invhess)
}
nloc <- npoints(loc)
switch(method,
interpreted = {
b <- numeric(nloc)
for(i in seq(nloc)) {
momi <- mom[i,, drop=FALSE]
b[i] <- momi %*% invhess %*% t(momi)
}
},
C = {
b <- quadform(mom, invhess)
})
if("leverage" %in% what) {
# values of leverage (diagonal) at points of 'loc'
h <- b * lam
levval <- loc %mark% h
levsmo <- smooth.ppp(levval, sigma=max(nndist(loc)))
# nominal mean level
a <- area.owin(loc$window)
levmean <- p/a
lev <- list(val=levval, smo=levsmo, ave=levmean)
result$lev <- lev
}
if("influence" %in% what) {
# values of influence at data points
X <- loc[isdata]
M <- (1/p) * b[isdata]
V <- X %mark% M
result$infl <- V
}
if("dfbetas" %in% what) {
vex <- invhess %*% t(mom)
switch(method,
interpreted = {
dis <- con <- matrix(0, nloc, ncol(mom))
for(i in seq(nloc)) {
vexi <- vex[,i, drop=FALSE]
dis[i, ] <- isdata[i] * vexi
con[i, ] <- - lam[i] * vexi
}
},
C = {
tvex <- t(vex)
dis <- isdata * tvex
con <- - lam * tvex
})
colnames(dis) <- colnames(con) <- colnames(mom)
result$dfbetas <- msr(Q, dis[isdata, ], con)
}
return(result)
}
plot.leverage.ppm <- function(x, ..., showcut=TRUE) {
fitname <- x$fitname
defaultmain <- paste("Leverage for", fitname)
y <- x$lev
do.call("plot.im",
resolve.defaults(list(y$smo),
list(...),
list(main=defaultmain)))
if(showcut)
contour(y$smo, levels=y$ave, add=TRUE, drawlabels=FALSE)
invisible(NULL)
}
plot.influence.ppm <- function(x, ...) {
fitname <- x$fitname
defaultmain <- paste("Influence for", fitname)
do.call("plot.ppp",
resolve.defaults(list(x$infl),
list(...),
list(main=defaultmain)))
}
as.im.leverage.ppm <- function(X, ...) {
return(X$lev$smo)
}
as.ppp.influence.ppm <- function(X, ...) {
return(X$infl)
}