partialpro: Case-local Partial Profiles for VarPro Variables

View source: R/partialpro.R

partialproR Documentation

Case-local Partial Profiles for VarPro Variables

Description

Estimate and display case-local partial effect profiles for selected variables from a fitted varpro object. The method constructs virtual twins by varying one feature at a time, evaluates a prediction learner on those virtual records, and optionally removes virtual records that are far from the observed covariate support using Unlimited Virtual Twins (UVT). UVT filtering can be based on isopro isolation forest support or on outpro OOD distances.

Usage

partialpro(object, xvar.names, nvar,
           target, learner, newdata, method = c("unsupv", "rnd", "auto"),
           verbose = FALSE, vt.filter = c("isopro", "outpro", "none"),
           ...)

Arguments

object

A varpro object returned by varpro.

xvar.names

Optional character vector of variables for which partial profiles are requested. If omitted, the variables returned by get.topvars(object) are used. Names not found in object$xvar.names are dropped with a warning listing the unavailable names. This check is applied after the nvar limit.

nvar

Optional integer limiting the number of variables used from xvar.names. If supplied, only the first nvar requested variables are used. If xvar.names is omitted, this limits the number of top VarPro variables.

target

For classification, the class for which the partial profile is computed. This can be either an integer column index or a character class label. The default is the last class level. For regression and survival outcomes this argument is ignored and the first prediction column is used.

learner

Optional prediction function. If omitted, partialpro uses the forest stored in object$rf. A supplied learner must accept a data frame of feature values with the same columns as object$x. It should return a numeric vector for regression or survival outcomes, or a matrix/data frame of class probabilities for classification outcomes. For classification, the column selected by target is used.

newdata

Optional data frame of cases on which the partial profiles are conditioned. If omitted, up to nsmp training cases are sampled from object$x separately for each requested variable. If supplied, all rows of newdata are used. The data must already be on the fitted VarPro x-scale, i.e. it must contain the columns of object$x. This is automatic when using rows from object$x, for example newdata = object$x[1:6, ]. Extra columns are ignored after alignment to colnames(object$x).

method

Isolation forest method used by isopro when vt.filter = "isopro" and cut != 0. Options are "unsupv", "rnd", and "auto". The default is "unsupv". If there is only one top variable and method = "unsupv", the code switches internally to "rnd". This argument is ignored when vt.filter = "outpro" or vt.filter = "none".

verbose

Logical. If TRUE, print the variable currently being processed.

vt.filter

Virtual twin filtering engine. The default "isopro" uses isolation forests through isopro. The option "outpro" uses out-of-distribution distances from outpro, calibrated through outpro.null. The option "none" disables virtual twin filtering, equivalent to setting cut = 0.

...

Advanced options controlling the virtual grid, UVT filtering, and local smoothing. These options are intentionally not part of the main argument list, but they are user-adjustable. See Advanced options in Details. Unnamed options, unrecognized names, and duplicate names cause an error.

Details

Method. For a requested variable xnm, partialpro creates a sequence of virtual values xvirtual. For each conditioning case, it constructs virtual twins by replacing xnm with each value in xvirtual while holding all other features fixed at that case's observed values. The prediction learner is then evaluated on the resulting virtual data.

The virtual grid is constructed as follows. Factors and variables with at most 10 unique observed values use their observed levels/values. Continuous variables with more than 10 unique values are trimmed to the central alpha to 1 - alpha empirical range and then represented by up to nvirtual quantile values. The actual number of grid points can be smaller than nvirtual if quantiles coincide.

If cut != 0 and vt.filter != "none", UVT filtering is applied before estimating the local profile. With vt.filter = "isopro", an isolation forest is fit by isopro using the top VarPro variables. Each virtual twin receives an isopro support score, and only virtual twins with score at least cut are treated as admissible.

With vt.filter = "outpro", virtual twins are scored by outpro on the fitted VarPro x-scale. The public outpro function normally hot-encodes raw newdata; here the virtual matrix is already aligned to object$x, so partialpro calls outpro with newdata.xscale = TRUE. The raw outpro distance is calibrated against the null/reference distance distribution from outpro.null and converted to a support score 1 - F0(distance). The same rule is then used: a virtual twin is admissible when this support score is at least cut. Thus cut = 0 disables UVT filtering, while larger values of cut retain fewer virtual twins. The default outpro distance for partialpro is "knn", which uses a standardized nearest-neighbor support calculation and avoids the forest-neighborhood computations used by several other outpro distances.

For regression and survival outcomes, learner predictions are used on their native prediction scale. For classification, the selected class probability is converted to a clipped log-odds scale using probabilities truncated to the interval [0.001, 0.999].

For continuous variables, a local polynomial profile is fit separately for each conditioning case using lm.fit and the design 1, x, x^2, ..., x^df. A case is retained if it has at least min(nmin, nxorg / 2) admissible virtual twins, where nxorg is the number of unique observed values of the variable. When UVT filtering is active and enough admissible training virtual twins are available, the code fits both a UVT-restricted polynomial and an unrestricted polynomial on a case-specific train split of virtual values. The unrestricted fit is used only if its held-out standardized MSE is lower than the UVT-restricted MSE by more than mse.tolerance; otherwise the UVT-restricted fit is used.

For binary variables, no polynomial extrapolation is used. The profile is computed directly from the mean predicted value at the two virtual values, and both virtual values must be admissible for a non-missing case-specific profile.

The component named yhat.causal is the case-specific profile centered at the first virtual value, i.e. the estimated contrast relative to xvirtual[1]. The name is retained for compatibility with the VarPro terminology, but causal interpretation requires the usual substantive and design assumptions; the function itself estimates model-based partial profiles and contrasts.

Advanced options supplied through ....

cut

UVT threshold. Virtual twins with support score less than cut are excluded. For vt.filter = "isopro", the support score is the isopro score. For vt.filter = "outpro", the support score is 1 - F0(distance), where F0 is the empirical null/reference CDF from outpro.null. Default is 0.1. Set cut = 0, or use vt.filter = "none", to turn off UVT filtering.

nsmp

Number of training cases sampled when newdata is omitted. The actual number is min(nrow(object$x), nsmp). Default is 250. This option is ignored when newdata is supplied.

nvirtual

Requested number of virtual grid values for a continuous variable with more than 10 unique values. Default is 100. The actual grid can be shorter if quantile values are tied. Factors and variables with at most 10 unique values use all observed levels/values instead.

nmin

Minimum number of admissible virtual twins required for a continuous-variable case profile, after applying the cap min(nmin, nxorg / 2). Default is 15.

alpha

Tail trimming used to define the continuous virtual grid. The grid is formed from values between the empirical alpha and 1 - alpha quantiles. Default is 0.025.

df

Degree of the local polynomial used for continuous variables. The value is rounded and constrained to be at least 1. Default is 2, giving a quadratic local profile.

sampsize

Sample-size function passed to isopro when vt.filter = "isopro" and UVT filtering is active. The default is function(x) min(2^8, 0.632 * x).

ntree

Number of trees used by the isopro isolation forest when vt.filter = "isopro" and UVT filtering is active. Default is 500.

nodesize

Terminal node size used by isopro when vt.filter = "isopro" and UVT filtering is active. Default is 1.

mse.tolerance

Tolerance in the held-out comparison between the UVT-restricted and unrestricted polynomial fits. The unrestricted fit is selected only when its standardized MSE is smaller by more than this amount. Default is 0.

out.distancef

Distance used by outpro when vt.filter = "outpro". The default is "knn". Other accepted values are those supported by outpro, including "prod", "euclidean", "mahalanobis", "manhattan", "minkowski", and "kernel".

out.neighbor

Neighbor count passed to outpro and outpro.null. The default NULL lets outpro choose its own value.

out.reduce

Reduced subspace passed to outpro when vt.filter = "outpro". The default NULL uses the top VarPro variables together with the focal variable currently being profiled. A character vector selects named variables; a named numeric vector selects variables and supplies their weights. In these two cases, the focal variable is added if absent. Other values, such as TRUE or FALSE, are passed through to outpro.

out.cutoff

Cutoff passed to outpro when out.reduce = TRUE. The default NULL lets outpro use its dimension-dependent default. This is not the virtual twin threshold; the virtual twin threshold is cut.

out.max.rules.tree

Maximum number of rules per tree passed to outpro for forest-neighborhood distances. Default is 150. This option has little effect for the default out.distancef = "knn".

out.max.tree

Maximum number of trees passed to outpro for forest-neighborhood distances. Default is 150. This option has little effect for the default out.distancef = "knn".

out.knn.chunk.size

Chunk size used by the outpro KNN distance calculation. Default is 100L. Increasing this value can be faster but uses more memory.

out.null

Optional precomputed outpro.null object, or a named list of such objects keyed by profiled variable name. This is mainly useful when repeatedly calling partialpro with vt.filter = "outpro" and the same calibration should be reused. If omitted, null calibration is computed internally and cached by reduced subspace.

Custom learner helpers. The package also supplies convenience learner constructors used in the examples. rf.learner(o, ...) re-fits a random forest using the top VarPro variables as a gentler variable-weighting scheme and passes recognized random-forest arguments through .... gbm.learner(o, ...) fits a gbm model with defaults n.trees = 500, shrinkage = 0.1, interaction.depth = 3, cv.folds = 5, and n.cores = get.mc.cores(); it uses Gaussian loss for regression/survival scores and Bernoulli loss for two-class classification. bart.learner(o, ...) fits a BART regression learner and accepts mc.cores for prediction; it applies only to regression/survival-style VarPro objects.

All three learner helpers require uniquely named options and reject unrecognized names before fitting. For rf.learner, formula, data, xvar.wt, and perf.type are set internally and cannot be supplied through ....

Because partialpro samples cases and creates case-specific train/test splits of the virtual grid, use set.seed before calling the function when reproducible profiles are needed.

Value

An invisible named list with class "partialpro". There is one named component for each requested variable that remains after matching to object$xvar.names. A component can be NULL if no usable virtual profiles are available for that variable. Otherwise each component is a list with the following elements:

case

Indices of the sampled training cases, or row numbers of newdata, retained for the variable.

xorg

Original observed values of the variable in object$x.

xvirtual

Virtual grid values used for the variable.

goodvt

Matrix with one row per retained case and one column per virtual value. Entries are 1 for admissible virtual twins and NA for virtual twins removed by UVT.

yhat.par

Case-specific fitted partial profile matrix on the prediction scale.

yhat.nonpar

Case-specific fitted partial profile matrix on the prediction scale. For the current continuous-variable implementation, this is the local fitted profile with a common global intercept added back.

yhat.causal

Case-specific contrast matrix centered at the first virtual value.

Author(s)

Min Lu and Hemant Ishwaran

References

Ishwaran H. (2025). Multivariate Statistics: Classical Foundations and Modern Machine Learning, CRC (Chapman and Hall), in press.

See Also

varpro, isopro, outpro

Examples




##------------------------------------------------------------------
##
## Boston housing
##
##------------------------------------------------------------------

library(mlbench)
data(BostonHousing)
oldpar <- par(mfrow=c(2,3))
plot((oo.boston<-partialpro(varpro(medv~.,BostonHousing),nvar=6)))
par(oldpar)

##------------------------------------------------------------------
##
## Boston housing using newdata option
##
##
##------------------------------------------------------------------

library(mlbench)
data(BostonHousing)
o <- varpro(medv~.,BostonHousing)
oldpar <- par(mfrow=c(2,3))
plot(partialpro(o,nvar=3))
## same analysis using outpro/KNN filtering
plot(partialpro(o,nvar=3,vt.filter="outpro"))
## same but using newdata (set to first 6 cases of the training data)
plot(partialpro(o,newdata=o$x[1:6,],nvar=3))
par(oldpar)

##------------------------------------------------------------------
##
## Boston housing with externally constructed rf learner
##
##------------------------------------------------------------------

## varpro analysis
library(mlbench)
data(BostonHousing)
o <- varpro(medv~.,BostonHousing)

## default partial pro call
pro <- partialpro(o, nvar=3)

## partial pro call using built in rf learner
mypro <- partialpro(o, nvar=3, learner=rf.learner(o))

## compare the two
oldpar <- par(mfrow=c(2,3))
plot(pro)
plot(mypro, ylab="external rf learner")
par(oldpar)

##------------------------------------------------------------------
##
## Boston housing:  tree gradient boosting learner, bart learner
##
##------------------------------------------------------------------

if (library("gbm", logical.return=TRUE) &&
    library("BART", logical.return=TRUE)) {

## varpro analysis
library(parallel)
library(mlbench)
data(BostonHousing)
o <- varpro(medv~.,BostonHousing)

## default partial pro call
pro <- partialpro(o, nvar=3)

## partial pro call using built in gradient boosting learner
mypro <- partialpro(o, nvar=3, learner=gbm.learner(o, n.trees=1000, n.cores=get.mc.cores()))

## partial pro call using built in bart learner
mypro2 <- partialpro(o, nvar=3, learner=bart.learner(o, mc.cores=get.mc.cores()))

## compare the learners
oldpar <- par(mfrow=c(3,3))
plot(pro)
plot(mypro, ylab="external boosting learner")
plot(mypro2, ylab="external bart learner")
par(oldpar)
}

##------------------------------------------------------------------
##
## peak vo2 with 5 year rmst
##
##------------------------------------------------------------------

data(peakVO2, package = "randomForestSRC")
oldpar <- par(mfrow=c(2,3))
plot((oo.peak<-partialpro(varpro(Surv(ttodead,died)~.,peakVO2,rmst=5),nvar=6)))
par(oldpar)

##------------------------------------------------------------------
##
## veteran data set with celltype as a factor
##
##------------------------------------------------------------------

data(veteran, package = "randomForestSRC")
dta <- veteran
dta$celltype <- factor(dta$celltype)
oldpar <- par(mfrow=c(2,3))
plot((oo.veteran<-partialpro(varpro(Surv(time, status)~., dta), nvar=6)))
par(oldpar)

##------------------------------------------------------------------
##
## iris: classification analysis showing partial effects for all classes
##
##------------------------------------------------------------------

o.iris <- varpro(Species~.,iris)
yl <- paste("log-odds", levels(iris$Species))
oldpar <- par(mfrow=c(3,2))
plot((oo.iris.1 <- partialpro(o.iris, target=1, nvar=2)),ylab=yl[1])
plot((oo.iris.2 <- partialpro(o.iris, target=2, nvar=2)),ylab=yl[2])
plot((oo.iris.3 <- partialpro(o.iris, target=3, nvar=2)),ylab=yl[3])
par(oldpar)

##------------------------------------------------------------------
##
## iowa housing data
##
##------------------------------------------------------------------

## quickly impute the data; log transform the outcome
data(housing, package = "randomForestSRC")
housing <- randomForestSRC::impute(SalePrice~., housing, splitrule="random", nimpute=1)
dta <- data.frame(data.matrix(housing))
dta$y <- log(housing$SalePrice)
dta$SalePrice <- NULL

## partial effects analysis
o.housing <- varpro(y~., dta, nvar=Inf)
oo.housing <- partialpro(o.housing,nvar=15)
oldpar <- par(mfrow=c(3,5))
plot(oo.housing)
par(oldpar)



varPro documentation built on Sept. 22, 2026, 5:09 p.m.

Related to partialpro in varPro...