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:
allcontains all the familiesparametriccontains the parametric families (all excepttll)nonparametriccontains the nonparametric families (indepandtll)one_parcontains the parametric families with a single parameter (gaussian,clayton,gumbel,frank, andjoe)two_parcontains the parametric families with two parameters (student,bb1,bb6,bb7, andbb8)three_parcontains the parametric families with three parameters (tawn)ellipticalcontains the elliptical familiesarchimedeancontains the archimedean familiesextreme_valuecontains the extreme-value families (gumbel,tawn)bbcontains the BB familiesitaufamilies 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_setdescribes 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_methoddescribes 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_methoddescribes the degree of the density approximation for the transformation kernel estimator. It can takeconstant(default),linearandquadraticfor approximations of degree zero, one and two.double nonparametric_multa factor with which the smoothing parameters are multiplied.std::string selection_criteriondescribes the criterion to compare the families. It can take either"loglik","aic", or"bic"(default).Eigen::VectorXd weightsan optional vector of weights for the observations.bool preselect_familiesdescribes 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_threadsnumber 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"));