Bivariate copula models
- Implemented bivariate copula families
- Set up a custom bivariate copula model
- Fit and select a bivariate copula
- Work with a bivariate copula model
Bivariate copula models are implemented as the Bicop
class, and BicopFamily
is a closely related enum class describing the type or "family" of copula. To use bivariate copula models in your code, include the header vinecopulib/
(or simply vinecopulib.hpp
) at the top of your source file.
Implemented bivariate copula families
type | name | BicopFamily |
---|---|---|
- | Independence | indep |
Elliptical | Gaussian | gaussian |
Student t | student | |
Archimedean | Clayton | clayton |
Gumbel | gumbel | |
Frank | frank | |
Joe | joe | |
BB1 | bb1 | |
BB6 | bb6 | |
BB7 | bb7 | |
BB8 | bb8 | |
Extreme-Value | Tawn | tawn |
Nonparametric | Transformation kernel | tll |
Note that several convenience vectors of families are included in the sub-namespace bicop_families
:
all
contains all the familiesparametric
contains the parametric families (all excepttll
)nonparametric
contains the nonparametric families (indep
andtll
)one_par
contains the parametric families with a single parameter (gaussian
,clayton
,gumbel
,frank
, andjoe
)two_par
contains the parametric families with two parameters (student
,bb1
,bb6
,bb7
, andbb8
)three_par
contains the parametric families with three parameters (tawn
)elliptical
contains the elliptical familiesarchimedean
contains the archimedean familiesextreme_value
contains the extreme-value families (gumbel
,tawn
)bb
contains the BB familiesitau
families for which estimation by Kendall's tau inversion is available (indep
,gaussian
,student
,clayton
,gumbel
,frank
,joe
)
// print all available families std::cout << "Available families : "; for (auto family : vinecopulib::bicop_families::all) { std::cout << get_family_name(family) << " "; }
Set up a custom bivariate copula model
There are essentially two ways of setting-up bivariate copulas:
- with known parameters,
- from data (i.e., with estimated parameters).
The constructor with known parameters takes 3 arguments:
- The copula family (default to
indep
) - The rotation (default to
0
) - The parameters (default to parameters corresponding to an independence copula)
// 90 degree rotated Clayton with default parameter (corresponds to independence) Bicop clayton(BicopFamily::clayton, 90); // Gauss copula with parameter 0.5 Bicop gauss(BicopFamily::gaussian, 0, Eigen::VectorXd::Constant(1, 0.5));
The constructor from data takes the same arguments as the select method and is described in the next section.
Fit and select a bivariate copula
You can either fit the parameters of a given Bicop
object with fit()
or select the best fitting model from a set of families with select()
.
create a Gauss copula with parameter 0.5 and simulate 1e3 observations Bicop model(BicopFamily::gaussian, 0, Eigen::VectorXd::Constant(1, 0.5)); auto data = model.simulate(1e3); instantiate a gaussian copula with default parameters and fit to data Bicop fitted(BicopFamily::gaussian); fitted.fit(data); std::cout << "estimated parameter: " << fitted.get_parameters() << std::endl; assign another family to the same variable and fit to data fitted = Bicop(BicopFamily::student); fitted.fit(data); std::cout << "estimated parameter: " << fitted.get_parameters() << std::endl; alternatively, assign to a family and fit automatically fitted.select(data); std::cout << "family: " << fitted.get_family_name() << "rotation: " << fitted.get_rotation() << std::endl;
As it's arguably the most important function of the Bicop
class, it's worth understanding the second argument of select()
, namely an object of the class FitControlsBicop
, which contain several data members:
std::vector<BicopFamily> family_set
describes the set of family to select from. It can take a user specified vector of families or any of those mentioned above (default isbicop_families::all
).std::string parametric_method
describes the estimation method. It can take"mle"
(default, for maximum-likelihood estimation) and"itau"
(for Kendall's tau inversion, although only available for families included inbicop_families::itau
).std::string nonparametric_method
describes the degree of the density approximation for the transformation kernel estimator. It can takeconstant
(default),linear
andquadratic
for approximations of degree zero, one and two.double nonparametric_mult
a factor with which the smoothing parameters are multiplied.std::string selection_criterion
describes the criterion to compare the families. It can take either"loglik"
,"aic"
, or"bic"
(default).Eigen::VectorXd weights
an optional vector of weights for the observations.bool preselect_families
describes a heuristic preselection method (default istrue
) based on symmetry properties of the data (e.g., the unrotated Clayton won't be preselected if the data displays upper-tail dependence).size_t num_threads
number of threads to run in parallel when fitting several families.
As mentioned above, the arguments of select()
can be used as arguments to a constructor allowing to instantiate a new object directly:
// instantiate an archimedean copula by selecting the "best" family according to // the BIC and parameters corresponding to the MLE Bicop best_archimedean(data, FitControlsBicop(bicop_families::archimedean)); std::cout << "family: " << best_archimedean.get_family_name() << "rotation: " << best_archimedean.get_rotation() << best_archimedean.get_parameters() << std::endl // instantiate a bivariate copula by selecting the "best" family according to // the AIC and parameters corresponding to Kendall's tau inversion FitControlsBicop controls(bicop_families::itau, "itau"); controls.set_selection_criterion("aic"); Bicop best_itau(data, controls)); std::cout << "family: " << best_itau.get_family_name() << "rotation: " << best_itau.get_rotation() << best_itau.get_parameters() << std::endl
Work with a bivariate copula model
You can simulate from a model and evaluate the pdf, h-functions, inverse h-functions, log-likelihood, AIC, and BIC.
// Gauss copula with parameter 0.5 Bicop bicop(BicopFamily::gaussian, 0, Eigen::VectorXd::Constant(1, 0.5)); // Simulate 100 observations auto sim_data = bicop.simulate(100); // Evaluate the pdf auto pdf = bicop.pdf(sim_data); // Evaluate the two h-functions auto h1 = bicop.hfunc1(sim_data); auto h2 = bicop.hfunc2(sim_data); // Evalute the two inverse h-functions auto hi1 = bicop.hinv1(sim_data); auto hi2 = bicop.hinv2(sim_data); // Evaluate the log-likelihood, AIC, and BIC auto ll = bicop.loglik(sim_data); auto aic = bicop.aic(sim_data); auto bic = bicop.bic(sim_data);
Bivariate copula models can also be written to and constructed from JSON files and nlohmann::json
objects:
// Gauss copula with parameter 0.5 Bicop bicop(BicopFamily::gaussian, 0, Eigen::VectorXd::Constant(1, 0.5)); // Save as a nlohmann::json object nlohmann::json bicop_json = bicop.to_json(); // Write into a JSON file std::string filename = "myfile.json" std::ofstream file(myfile); file << bicop_json << std::endl; // Equivalently bicop.to_file(std::string("myfile.json")); // Then a new Bicop can be constructed from the nlohmann::json object Bicop bicop2(bicop_json); // Or from the JSON file Bicop bicop3(std::string("myfile.json"));