Fitting compound distributions

Through the SklarDist interface, there is the possibility to fit directly distributions that are constructed from a copula and some marginals:

using Copulas
using Distributions

# Let's sample some datas:
X₁ = LogNormal()
X₂ = Pareto()
X₃ = Gamma()
X₄ = Normal()
C = SurvivalCopula(FrankCopula(4,7),(2,4))
D = SklarDist(C,(X₁,X₂,X₃,X₄))
data = rand(D,1000)
4×1000 Matrix{Float64}:
 0.572934  0.577963  0.225804   1.68402   …  0.40018   0.367618  0.438113
 8.64858   1.36593   5.60143    1.22183      5.2911    2.35829   3.01878
 0.370906  0.334487  0.0250247  1.50776      0.255431  0.188241  1.01831
 0.627368  0.120055  1.48898    0.156953     1.29231   1.02646   0.130719

The fit function uses a type as its first argument that describes the structure of the model :

MyCop = SurvivalCopula{4,ClaytonCopula,(2,4)}
MyMargs = Tuple{LogNormal,Pareto,Gamma,Normal}
MyD = SklarDist{MyCop, MyMargs}
fitted_model = fit(MyD,data)
SklarDist{SurvivalCopula{4, ClaytonCopula{4, Float64}, Tuple{Int64, Int64}}, Tuple{Distributions.LogNormal{Float64}, Distributions.Pareto{Float64}, Distributions.Gamma{Float64}, Distributions.Normal{Float64}}}(
C: SurvivalCopula{4, ClaytonCopula{4, Float64}, Tuple{Int64, Int64}}(
C: ClaytonCopula{4, Float64}(
G: Copulas.ClaytonGenerator{Float64}(2.4848417735252166)
)

indices: (2, 4)
)

m: (Distributions.LogNormal{Float64}(μ=0.016875188289571155, σ=0.9734699846396494), Distributions.Pareto{Float64}(α=1.0467158498271152, θ=1.003166246355492), Distributions.Gamma{Float64}(α=1.0590369807654998, θ=0.9380364297096385), Distributions.Normal{Float64}(μ=-0.021535633837128802, σ=0.9819713287700214))
)

Another possibility is to use an empirical copula and only fit the marginals:

other_fitted_model = fit(SklarDist{EmpiricalCopula,MyMargs},data)
SklarDist{EmpiricalCopula{4, LinearAlgebra.Transpose{Float64, Matrix{Float64}}}, Tuple{Distributions.LogNormal{Float64}, Distributions.Pareto{Float64}, Distributions.Gamma{Float64}, Distributions.Normal{Float64}}}(
C: EmpiricalCopula{4, LinearAlgebra.Transpose{Float64, Matrix{Float64}}}(
u: [0.26373626373626374 0.2677322677322677 … 0.14885114885114886 0.18981018981018982; 0.8921078921078921 0.2807192807192807 … 0.5824175824175825 0.6813186813186813; 0.3076923076923077 0.2707292707292707 … 0.15884115884115885 0.6263736263736264; 0.7572427572427572 0.5804195804195804 … 0.8571428571428571 0.5854145854145855]
)

m: (Distributions.LogNormal{Float64}(μ=0.016875188289571155, σ=0.9734699846396494), Distributions.Pareto{Float64}(α=1.0467158498271152, θ=1.003166246355492), Distributions.Gamma{Float64}(α=1.0590369807654998, θ=0.9380364297096385), Distributions.Normal{Float64}(μ=-0.021535633837128802, σ=0.9819713287700214))
)

This simple interface leverages indeed the fit function from Distributions.jl. From their documentation, this function is not supposed to use a particular method but to fit "dirt and quick" some distributions.

So you have to be careful: the fit method might not be the same for different copulas or different marginals. For example, the Archimedean copulas are fitted through an inversion of the Kendall tau function, while the Gaussian copula is fitted by maximum likelihood.