| partialpro | R Documentation |
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.
partialpro(object, xvar.names, nvar,
target, learner, newdata, method = c("unsupv", "rnd", "auto"),
verbose = FALSE, vt.filter = c("isopro", "outpro", "none"),
...)
object |
A |
xvar.names |
Optional character vector of variables for which partial
profiles are requested. If omitted, the variables returned by
|
nvar |
Optional integer limiting the number of variables used from
|
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,
|
newdata |
Optional data frame of cases on which the partial profiles
are conditioned. If omitted, up to |
method |
Isolation forest method used by |
verbose |
Logical. If |
vt.filter |
Virtual twin filtering engine. The default
|
... |
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 |
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 ....
cutUVT 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.
nsmpNumber 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.
nvirtualRequested 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.
nminMinimum number of admissible virtual twins required for a
continuous-variable case profile, after applying the cap
min(nmin, nxorg / 2). Default is 15.
alphaTail 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.
dfDegree 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.
sampsizeSample-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).
ntreeNumber of trees used by the isopro isolation
forest when vt.filter = "isopro" and UVT filtering is active.
Default is 500.
nodesizeTerminal node size used by isopro when
vt.filter = "isopro" and UVT filtering is active. Default is
1.
mse.toleranceTolerance 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.distancefDistance 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.neighborNeighbor count passed to outpro and
outpro.null. The default NULL lets outpro choose its
own value.
out.reduceReduced 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.cutoffCutoff 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.treeMaximum 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.treeMaximum 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.sizeChunk size used by the outpro KNN
distance calculation. Default is 100L. Increasing this value can be
faster but uses more memory.
out.nullOptional 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.
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:
caseIndices of the sampled training cases, or row numbers
of newdata, retained for the variable.
xorgOriginal observed values of the variable in
object$x.
xvirtualVirtual grid values used for the variable.
goodvtMatrix 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.parCase-specific fitted partial profile matrix on the prediction scale.
yhat.nonparCase-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.causalCase-specific contrast matrix centered at the first virtual value.
Min Lu and Hemant Ishwaran
Ishwaran H. (2025). Multivariate Statistics: Classical Foundations and Modern Machine Learning, CRC (Chapman and Hall), in press.
varpro,
isopro,
outpro
##------------------------------------------------------------------
##
## 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)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.