A vine copula decomposes a multivariate dependence model into a
sequence of bivariate copulas. The structure determines which
conditioned and conditioning variables belong to each edge; one
bicop_dist object supplies the model for that edge.
Consider the triangular array
4 4 4 4
3 3 3
2 2
1
It represents these pair copulas:
| Tree | Edge | Conditioned pair | Conditioning set |
|---|---|---|---|
| 1 | 1 | 1, 4 | — |
| 1 | 2 | 2, 4 | — |
| 1 | 3 | 3, 4 | — |
| 2 | 1 | 1, 3 | 4 |
| 2 | 2 | 2, 3 | 4 |
| 3 | 1 | 1, 2 | 3, 4 |
In R, the structure can be constructed from its order and off-diagonal rows:
structure <- rvine_structure(
order = 1:4,
struct_array = list(c(4, 4, 4), c(3, 3), 2)
)
structure
#> 4-dimensional R-vine structure ('rvine_structure')
#> 4 4 4 4
#> 3 3 3
#> 2 2
#> 1
as_rvine_matrix(structure)
#> 4-dimensional R-vine matrix ('rvine_matrix')
#> 4 4 4 4
#> 3 3 3
#> 2 2
#> 1The square R-vine matrix contains the same information with zeros
filling the unused triangle. as_rvine_structure() converts
it back to the compressed representation.
cvine_structure() and dvine_structure()
construct the two common order-determined special cases. Random valid
structures are available through rvine_structure_sim().
cvine_structure(c(4, 1, 3, 2))
#> 4-dimensional R-vine structure ('rvine_structure')
#> 2 2 2 2
#> 3 3 3
#> 1 1
#> 4
dvine_structure(c(4, 1, 3, 2))
#> 4-dimensional R-vine structure ('rvine_structure')
#> 1 3 2 2
#> 3 2 3
#> 2 1
#> 4
rvine_structure_sim(4)
#> 4-dimensional R-vine structure ('rvine_structure')
#> 3 3 3 3
#> 1 1 1
#> 4 4
#> 2See ?rvine_structure for the complete validity and
proximity conditions.
For a three-dimensional model, the first tree has two pair copulas
and the second has one. The nested list follows
pair_copulas[[tree]][[edge]].
pair_copulas <- list(
list(
bicop_dist("gaussian", parameters = 0.6),
bicop_dist("clayton", parameters = 1.5)
),
list(bicop_dist("frank", parameters = 2))
)
model <- vinecop_dist(
pair_copulas,
structure = dvine_structure(1:3)
)
model
#> 3-dimensional vine copula model ('vinecop_dist')
summary(model)
#> # A data.frame: 3 x 10
#> tree edge conditioned conditioning var_types family rotation parameters df
#> 1 1 1, 2 c,c gaussian 0 0.6 1
#> 1 2 2, 3 c,c clayton 0 1.5 1
#> 2 1 1, 3 2 c,c frank 0 2 1
#> tau
#> 0.41
#> 0.43
#> 0.21The model can immediately be evaluated and simulated:
With no structure supplied, vinecop() selects trees
sequentially using the Dissmann algorithm and fits a pair copula on
every selected edge.
n <- 150
z <- rnorm(n)
x <- cbind(
z + rnorm(n, sd = 0.7),
0.6 * z + rnorm(n),
-0.4 * z + rnorm(n),
rnorm(n)
)
u <- pseudo_obs(x)
fit <- vinecop(u, family_set = "onepar", selcrit = "bic")
fit
#> 4-dimensional vine copula fit ('vinecop')
#> nobs = 150 logLik = 17.21 npars = 6 AIC = -22.42 BIC = -4.36
summary(fit)
#> # A data.frame: 6 x 11
#> tree edge conditioned conditioning var_types family rotation parameters df
#> 1 1 4, 2 c,c joe 0 1.1 1
#> 1 2 3, 1 c,c frank 0 -1.3 1
#> 1 3 2, 1 c,c gaussian 0 0.33 1
#> 2 1 4, 1 2 c,c joe 90 1.1 1
#> 2 2 3, 2 1 c,c clayton 270 0.15 1
#> 3 1 4, 3 1, 2 c,c joe 90 1.2 1
#> tau loglik
#> 0.060 1.4
#> -0.143 3.3
#> 0.217 8.1
#> -0.043 1.3
#> -0.068 1.2
#> -0.087 2.0The most important pair-copula controls (family_set,
par_method, nonpar_method, mult,
selcrit, weights, presel, and
allow_rotations) have the same meaning as in
bicop(). The bivariate
copula guide describes the available families, rotations, and
estimation methods.
Getters work on both manually constructed and fitted models. Tree and edge indices are one-based in the R interface.
get_structure(fit)
#> 4-dimensional R-vine structure ('rvine_structure')
#> 2 1 1 1
#> 1 2 2
#> 3 3
#> 4
get_matrix(fit)
#> 4-dimensional R-vine matrix ('rvine_matrix')
#> 2 1 1 1
#> 1 2 2
#> 3 3
#> 4
get_pair_copula(fit, tree = 1, edge = 1)
#> Bivariate copula fit ('bicop'): family = joe, rotation = 0, parameters = 1.11, var_types = c,c
get_family(fit, tree = 1, edge = 1)
#> [1] "joe"
get_parameters(fit, tree = 1, edge = 1)
#> [,1]
#> [1,] 1.111375
get_ktau(fit, tree = 1, edge = 1)
#> [1] 0.06016693
get_all_families(fit)
#> Nested list of lists for the copula families of a 4 dimensional vine with all trees:
#> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#> x[[1]] -> a list with the 3 copula families of tree 1.
#> x[[2]] -> a list with the 2 copula families of tree 2.
#> x[[3]] -> a list with the 1 copula families of tree 3.summary(fit) returns the edge table invisibly, which is
convenient for programmatic inspection.
The edge weight used to build each tree is selected by
tree_crit:
"tau" for absolute Kendall’s tau;"rho" for absolute Spearman’s rho;"hoeffd" for Hoeffding’s D;"mcor" for maximum correlation;"cxi" for symmetrized Chatterjee’s xi;"joe" for a Gaussian-copula mutual-information
criterion;data and
weights.tree_algorithm = "mst_prim" and
"mst_kruskal" select a maximum spanning tree.
"random_weighted" and "random_unweighted" draw
random spanning trees, which can be useful in ensemble or exploratory
workflows.
custom_strength <- function(data, weights) {
if (length(weights)) {
abs(weighted.mean(data[, 1] * data[, 2], weights))
} else {
abs(mean(data[, 1] * data[, 2]))
}
}
custom_fit <- vinecop(u, tree_crit = custom_strength)
random_fit <- vinecop(u, tree_algorithm = "random_weighted")Custom criteria run on the calling thread. Pair-copula fitting may
still use multiple cores.
Supply a full structure to keep it fixed while selecting pair-copula
families. A truncated structure fixes its existing trees and asks
vinecop() to select the remaining trees up to
trunc_lvl.
trunc_lvl limits the number of fitted trees. Pair
copulas above that level are independence copulas.
threshold replaces edges whose selection strength is below
the threshold by independence copulas.
truncated <- vinecop(u, family_set = "onepar", trunc_lvl = 1)
thresholded <- vinecop(u, family_set = "onepar", threshold = 0.1)
truncate_model(fit, trunc_lvl = 1)
#> 4-dimensional vine copula fit ('vinecop'), 1-truncated
#> nobs = 150 logLik = 12.74 npars = 3 AIC = -19.49 BIC = -10.46Set trunc_lvl = NA or threshold = NA to
select the value automatically with mBICV. The fitted threshold and
truncation level are visible in the model summary.
Pass a fitted model through vinecop_object to update
parameters while keeping its structure and families fixed. This is
useful for rolling windows or bootstrap samples.
refitted <- vinecop(u, vinecop_object = fit)
stopifnot(identical(get_all_families(refitted), get_all_families(fit)))For a manually constructed distribution, use vinecop()
to select from data or construct a new vinecop_dist() after
changing its components.