分层Copula与Pair-Copula计算指南

分层Copula与Pair-Copula计算指南

一、理论基础与概念解析

1.1 分层Copula(Hierarchical Copula)

分层Copula通过嵌套结构建模多变量依赖关系,特别适合处理多尺度依赖非对称依赖

分层Copula结构:
┌─────────────────────────────────────────────────────────────┐
│                    全局Copula (顶层)                        │
│                     C_θ₀(u₁, u₂, ..., uₙ)                  │
├─────────────────────────────────────────────────────────────┤
│  局部Copula 1    │  局部Copula 2    │   ...  │  局部Copula k │
│  C_θ₁(u₁, u₂)   │  C_θ₂(u₃, u₄)   │       │  C_θₖ(uₙ₋₁,uₙ)│
└─────────────────────────────────────────────────────────────┘

1.2 Pair-Copula(R-Vine结构)

Pair-Copula分解将多维Copula分解为一系列二元Copula的乘积:


二、MATLAB实现代码

2.1 主程序:hierarchical_paircopula_main.m

%% 分层Copula与Pair-Copula计算系统
% 功能:实现分层Copula和Pair-Copula(R-Vine)的建模与计算

clear; clc; close all;

%% 1. 系统参数配置
fprintf('=== 分层Copula与Pair-Copula计算系统 ===\n');
params = configure_copula_parameters();

fprintf('Copula系统配置:\n');
fprintf('  变量维度: %d\n', params.dim);
fprintf('  样本数量: %d\n', params.n_samples);
fprintf('  分层结构: %s\n', params.hierarchy_type);
fprintf('  Pair-Copula类型: %s\n', params.paircopula_type);
fprintf('  优化方法: %s\n\n', params.optimization_method);

%% 2. 生成/加载数据
fprintf('生成/加载数据...\n');
data = generate_copula_data(params);

%% 3. 分层Copula建模
fprintf('构建分层Copula模型...\n');
tic;
hierarchical_copula = build_hierarchical_copula(data, params);
hierarchical_time = toc;
fprintf('  分层Copula构建完成!耗时: %.3f秒\n', hierarchical_time);

%% 4. Pair-Copula(R-Vine)建模
fprintf('构建Pair-Copula(R-Vine)模型...\n');
tic;
rvine_model = build_rvine_model(data, params);
rvine_time = toc;
fprintf('  R-Vine模型构建完成!耗时: %.3f秒\n', rvine_time);

%% 5. 模型比较与选择
fprintf('模型比较与选择...\n');
model_comparison = compare_copula_models(hierarchical_copula, rvine_model, data, params);

%% 6. 依赖结构分析
fprintf('依赖结构分析...\n');
dependency_analysis = analyze_dependency_structure(rvine_model, params);

%% 7. 风险度量计算
fprintf('风险度量计算...\n');
risk_measures = calculate_risk_measures(hierarchical_copula, rvine_model, params);

%% 8. 可视化结果
visualize_copula_results(hierarchical_copula, rvine_model, dependency_analysis, risk_measures, params);

2.2 参数配置:configure_copula_parameters.m

function params = configure_copula_parameters()
    % 配置Copula系统参数
    
    %% 基本参数
    params.dim = 5;                  % 变量维度(资产数量)
    params.n_samples = 1000;         % 样本数量
    params.seed = 42;                % 随机种子
    
    %% 分层结构参数
    params.hierarchy_type = 'binary_tree';  % 分层类型: 'binary_tree', 'star', 'custom'
    params.n_levels = 3;             % 分层级数
    params.clustering_method = 'ward'; % 聚类方法
    
    %% Pair-Copula参数
    params.paircopula_type = 'rvine'; % Pair-Copula类型: 'rvine', 'dvine', 'cvine'
    params.copula_families = {'gaussian', 't', 'clayton', 'gumbel', 'frank'};
    params.selection_criterion = 'aic'; % 选择准则: 'aic', 'bic'
    
    %% 优化参数
    params.optimization_method = 'ml'; % 优化方法: 'ml', 'itau'
    params.max_iter = 1000;          % 最大迭代次数
    params.tolerance = 1e-6;         % 收敛容差
    
    %% 风险度量参数
    params.confidence_level = 0.95;  % 置信水平
    params.time_horizon = 1;         % 时间跨度(年)
    params.n_simulations = 10000;    % 蒙特卡洛模拟次数
    
    %% 可视化参数
    params.plot_resolution = 50;      % 绘图分辨率
    
    fprintf('Copula参数配置完成!\n');
end

2.3 数据生成:generate_copula_data.m

function data = generate_copula_data(params)
    % 生成Copula建模数据
    
    rng(params.seed); % 设置随机种子
    
    % 生成多元正态分布数据(作为基础)
    mu = zeros(params.dim, 1);
    Sigma = generate_correlation_matrix(params.dim);
    
    % 生成多元正态样本
    normal_samples = mvnrnd(mu, Sigma, params.n_samples);
    
    % 转换为均匀分布(概率积分变换)
    uniform_samples = zeros(params.n_samples, params.dim);
    for i = 1:params.dim
        uniform_samples(:, i) = normcdf(normal_samples(:, i), mu(i), sqrt(Sigma(i, i)));
    end
    
    % 添加尾部依赖(可选)
    if params.dim >= 3
        % 在部分变量间添加Clayton Copula依赖
        clayton_samples = copularnd('Clayton', 2, params.n_samples);
        uniform_samples(:, 1:2) = clayton_samples(:, 1:2);
    end
    
    % 组织数据结构
    data.uniform = uniform_samples;
    data.normal = normal_samples;
    data.correlation = Sigma;
    data.names = cellstr(num2str((1:params.dim)', 'Asset_%d'));
    
    fprintf('  生成 %d 个样本,%d 个变量\n', params.n_samples, params.dim);
    fprintf('  相关性矩阵条件数: %.2f\n', cond(Sigma));
end

function Sigma = generate_correlation_matrix(dim)
    % 生成相关矩阵
    Sigma = eye(dim);
    
    % 设置合理的相关系数
    for i = 1:dim
        for j = i+1:dim
            if i == j
                Sigma(i, j) = 1;
            else
                % 生成-0.3到0.8之间的相关系数
                rho = -0.3 + 1.1 * rand();
                Sigma(i, j) = rho;
                Sigma(j, i) = rho;
            end
        end
    end
    
    % 确保正定性
    [V, D] = eig(Sigma);
    D = diag(max(diag(D), 0.01));
    Sigma = V * D * V';
end

2.4 分层Copula构建:build_hierarchical_copula.m

function hierarchical_copula = build_hierarchical_copula(data, params)
    % 构建分层Copula模型
    
    fprintf('  1. 变量聚类分析...\n');
    clusters = perform_variable_clustering(data, params);
    
    fprintf('  2. 构建分层结构...\n');
    hierarchy = build_hierarchy_structure(clusters, params);
    
    fprintf('  3. 估计每层Copula参数...\n');
    copula_params = estimate_hierarchical_parameters(data, hierarchy, params);
    
    fprintf('  4. 验证分层Copula...\n');
    validation_results = validate_hierarchical_copula(data, hierarchy, copula_params, params);
    
    % 组织输出结构
    hierarchical_copula = struct();
    hierarchical_copula.hierarchy = hierarchy;
    hierarchical_copula.parameters = copula_params;
    hierarchical_copula.validation = validation_results;
    hierarchical_copula.loglikelihood = validation_results.loglikelihood;
    hierarchical_copula.aic = -2 * validation_results.loglikelihood + 2 * count_parameters(copula_params);
    
    fprintf('    分层CopulaAIC: %.2f\n', hierarchical_copula.aic);
end

function clusters = perform_variable_clustering(data, params)
    % 变量聚类分析
    n_vars = size(data.uniform, 2);
    
    % 计算距离矩阵(基于Kendall's tau)
    distance_matrix = zeros(n_vars, n_vars);
    for i = 1:n_vars
        for j = i+1:n_vars
            tau = corr(data.uniform(:, i), data.uniform(:, j), 'Type', 'Kendall');
            distance_matrix(i, j) = 1 - abs(tau);
            distance_matrix(j, i) = distance_matrix(i, j);
        end
    end
    
    % 层次聚类
    linkage_tree = linkage(distance_matrix, params.clustering_method);
    
    % 确定聚类数量
    n_clusters = max(2, floor(n_vars / 2));
    
    % 获取聚类分配
    cluster_assignments = cluster(linkage_tree, 'maxclust', n_clusters);
    
    % 组织聚类结果
    clusters = struct();
    clusters.tree = linkage_tree;
    clusters.assignments = cluster_assignments;
    clusters.n_clusters = n_clusters;
    clusters.distance_matrix = distance_matrix;
    
    fprintf('    聚类完成:%d个变量分为%d个簇\n', n_vars, n_clusters);
end

function hierarchy = build_hierarchy_structure(clusters, params)
    % 构建分层结构
    n_vars = length(clusters.assignments);
    
    switch params.hierarchy_type
        case 'binary_tree'
            hierarchy = build_binary_tree(clusters, n_vars);
        case 'star'
            hierarchy = build_star_structure(clusters, n_vars);
        case 'custom'
            hierarchy = build_custom_structure(clusters, n_vars);
        otherwise
            error('未知的分层类型: %s', params.hierarchy_type);
    end
    
    fprintf('    分层结构构建完成:%d层\n', hierarchy.n_levels);
end

function hierarchy = build_binary_tree(clusters, n_vars)
    % 构建二叉树分层结构
    hierarchy = struct();
    hierarchy.n_levels = ceil(log2(n_vars));
    hierarchy.levels = cell(hierarchy.n_levels, 1);
    
    % 第一层:原始变量
    hierarchy.levels{1} = (1:n_vars)';
    
    % 后续层:聚类合并
    current_clusters = unique(clusters.assignments);
    for level = 2:hierarchy.n_levels
        if level == 2
            hierarchy.levels{level} = current_clusters;
        else
            % 继续合并聚类
            n_current = length(current_clusters);
            new_clusters = cell(ceil(n_current/2), 1);
            for i = 1:2:min(n_current, length(new_clusters)*2)
                if i+1 <= n_current
                    new_clusters{ceil(i/2)} = [current_clusters(i), current_clusters(i+1)];
                else
                    new_clusters{ceil(i/2)} = current_clusters(i);
                end
            end
            hierarchy.levels{level} = new_clusters;
            current_clusters = new_clusters;
        end
    end
    
    hierarchy.type = 'binary_tree';
end

function copula_params = estimate_hierarchical_parameters(data, hierarchy, params)
    % 估计分层Copula参数
    copula_params = struct();
    
    % 逐层估计Copula参数
    for level = 1:hierarchy.n_levels
        level_nodes = hierarchy.levels{level};
        
        if iscell(level_nodes)
            % 处理聚类节点
            for node_idx = 1:length(level_nodes)
                node = level_nodes{node_idx};
                if isvector(node) && length(node) > 1
                    % 估计该聚类的Copula参数
                    node_data = data.uniform(:, node);
                    copula_params = estimate_node_copula(node_data, node, level, node_idx, copula_params, params);
                end
            end
        else
            % 处理单个变量
            for var_idx = 1:length(level_nodes)
                var_id = level_nodes(var_idx);
                copula_params = estimate_variable_copula(data.uniform(:, var_id), var_id, level, var_idx, copula_params, params);
            end
        end
    end
    
    fprintf('    参数估计完成\n');
end

function copula_params = estimate_node_copula(node_data, node, level, node_idx, copula_params, params)
    % 估计节点Copula参数
    n_vars_in_node = size(node_data, 2);
    
    % 选择合适的Copula族
    best_family = select_copula_family(node_data, params);
    
    % 估计参数
    switch best_family
        case 'gaussian'
            rho = corr(node_data, 'Type', 'Pearson');
            copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 'gaussian', 'rho', rho);
        case 't'
            [rho, nu] = copulafit('t', node_data);
            copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 't', 'rho', rho, 'nu', nu);
        case 'clayton'
            alpha = copulafit('Clayton', node_data);
            copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 'clayton', 'alpha', alpha);
        case 'gumbel'
            alpha = copulafit('Gumbel', node_data);
            copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 'gumbel', 'alpha', alpha);
        case 'frank'
            alpha = copulafit('Frank', node_data);
            copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 'frank', 'alpha', alpha);
    end
end

function best_family = select_copula_family(data, params)
    % 选择最佳Copula族
    best_family = 'gaussian';
    best_aic = inf;
    
    for family_idx = 1:length(params.copula_families)
        family = params.copula_families{family_idx};
        
        try
            % 估计参数
            switch lower(family)
                case 'gaussian'
                    rho = corr(data, 'Type', 'Pearson');
                    loglik = calculate_gaussian_loglikelihood(data, rho);
                case 't'
                    [rho, nu] = copulafit('t', data);
                    loglik = calculate_t_loglikelihood(data, rho, nu);
                case 'clayton'
                    alpha = copulafit('Clayton', data);
                    loglik = calculate_clayton_loglikelihood(data, alpha);
                case 'gumbel'
                    alpha = copulafit('Gumbel', data);
                    loglik = calculate_gumbel_loglikelihood(data, alpha);
                case 'frank'
                    alpha = copulafit('Frank', data);
                    loglik = calculate_frank_loglikelihood(data, alpha);
            end
            
            % 计算AIC
            n_params = count_family_parameters(family);
            aic = -2 * loglik + 2 * n_params;
            
            if aic < best_aic
                best_aic = aic;
                best_family = family;
            end
        catch
            continue;
        end
    end
end

2.5 R-Vine模型构建:build_rvine_model.m

function rvine_model = build_rvine_model(data, params)
    % 构建R-Vine(Regular Vine)模型
    
    fprintf('  1. 选择Vine结构...\n');
    vine_structure = select_vine_structure(data, params);
    
    fprintf('  2. 估计Pair-Copula参数...\n');
    pair_copulas = estimate_pair_copulas(data, vine_structure, params);
    
    fprintf('  3. 计算条件分布...\n');
    conditional_distributions = calculate_conditional_distributions(data, vine_structure, pair_copulas, params);
    
    fprintf('  4. 验证R-Vine模型...\n');
    validation_results = validate_rvine_model(data, vine_structure, pair_copulas, params);
    
    % 组织输出结构
    rvine_model = struct();
    rvine_model.structure = vine_structure;
    rvine_model.pair_copulas = pair_copulas;
    rvine_model.conditional_distributions = conditional_distributions;
    rvine_model.validation = validation_results;
    rvine_model.loglikelihood = validation_results.loglikelihood;
    rvine_model.aic = -2 * validation_results.loglikelihood + 2 * count_rvine_parameters(pair_copulas);
    
    fprintf('    R-Vine模型AIC: %.2f\n', rvine_model.aic);
end

function vine_structure = select_vine_structure(data, params)
    % 选择Vine结构
    n_vars = size(data.uniform, 2);
    
    switch params.paircopula_type
        case 'rvine'
            vine_structure = select_regular_vine(data, params);
        case 'dvine'
            vine_structure = select_d_vine(n_vars);
        case 'cvine'
            vine_structure = select_c_vine(n_vars);
        otherwise
            error('未知的Pair-Copula类型: %s', params.paircopula_type);
    end
    
    fprintf('    Vine结构选择完成\n');
end

function vine_structure = select_regular_vine(data, params)
    % 选择正则Vine结构(基于最大生成树)
    n_vars = size(data.uniform, 2);
    
    % 计算Kendall's tau矩阵
    tau_matrix = zeros(n_vars, n_vars);
    for i = 1:n_vars
        for j = i+1:n_vars
            tau = corr(data.uniform(:, i), data.uniform(:, j), 'Type', 'Kendall');
            tau_matrix(i, j) = abs(tau);
            tau_matrix(j, i) = abs(tau);
        end
    end
    
    % 构建最大生成树(基于Kruskal算法)
    edges = [];
    for i = 1:n_vars
        for j = i+1:n_vars
            edges = [edges; i, j, tau_matrix(i, j)];
        end
    end
    
    % 按权重降序排序
    [~, idx] = sort(edges(:, 3), 'descend');
    edges = edges(idx, :);
    
    % Kruskal算法
    parent = 1:n_vars;
    tree_edges = [];
    
    for edge_idx = 1:size(edges, 1)
        i = edges(edge_idx, 1);
        j = edges(edge_idx, 2);
        
        % 查找根节点
        root_i = find_root(parent, i);
        root_j = find_root(parent, j);
        
        if root_i ~= root_j
            tree_edges = [tree_edges; i, j];
            parent(root_j) = root_i;
            
            if size(tree_edges, 1) == n_vars - 1
                break;
            end
        end
    end
    
    % 组织Vine结构
    vine_structure = struct();
    vine_structure.n_trees = n_vars - 1;
    vine_structure.trees = cell(vine_structure.n_trees, 1);
    vine_structure.trees{1} = tree_edges;
    
    % 构建后续树(简化版)
    for tree_idx = 2:vine_structure.n_trees
        vine_structure.trees{tree_idx} = generate_next_tree(vine_structure.trees{tree_idx-1}, n_vars);
    end
    
    vine_structure.type = 'regular_vine';
end

function root = find_root(parent, node)
    % 查找根节点
    while parent(node) ~= node
        node = parent(node);
    end
    root = node;
end

function next_tree = generate_next_tree(prev_tree, n_vars)
    % 生成下一棵树(简化版)
    next_tree = [];
    n_edges = size(prev_tree, 1);
    
    for i = 1:n_edges-1
        for j = i+1:n_edges
            % 检查是否有共同节点
            common_nodes = intersect(prev_tree(i, :), prev_tree(j, :));
            if ~isempty(common_nodes)
                % 创建新边
                new_edge = setdiff([prev_tree(i, :), prev_tree(j, :)], common_nodes);
                if length(new_edge) == 2
                    next_tree = [next_tree; new_edge];
                end
            end
        end
    end
end

function pair_copulas = estimate_pair_copulas(data, vine_structure, params)
    % 估计Pair-Copula参数
    pair_copulas = struct();
    n_trees = vine_structure.n_trees;
    
    for tree_idx = 1:n_trees
        tree_edges = vine_structure.trees{tree_idx};
        n_edges = size(tree_edges, 1);
        
        for edge_idx = 1:n_edges
            % 获取边的端点
            u = tree_edges(edge_idx, 1);
            v = tree_edges(edge_idx, 2);
            
            % 获取条件变量(简化版)
            condition_vars = [];
            if tree_idx > 1
                % 查找条件变量
                condition_vars = find_condition_variables(vine_structure.trees{tree_idx-1}, u, v);
            end
            
            % 估计Pair-Copula参数
            if isempty(condition_vars)
                edge_data = data.uniform(:, [u, v]);
            else
                edge_data = data.uniform(:, [u, v, condition_vars]);
            end
            
            % 选择最佳Copula族
            best_family = select_copula_family(edge_data, params);
            
            % 估计参数
            copula_params = estimate_edge_copula(edge_data, best_family, params);
            
            % 存储结果
            edge_name = sprintf('tree%d_edge%d_%d_%d', tree_idx, edge_idx, u, v);
            pair_copulas.(edge_name) = struct('u', u, 'v', v, 'condition_vars', condition_vars, ...
                                              'family', best_family, 'params', copula_params);
        end
    end
    
    fprintf('    Pair-Copula参数估计完成\n');
end

function condition_vars = find_condition_variables(prev_tree, u, v)
    % 查找条件变量
    condition_vars = [];
    
    for edge_idx = 1:size(prev_tree, 1)
        edge = prev_tree(edge_idx, :);
        if ismember(u, edge) && ismember(v, edge)
            % 找到共同边
            common_vars = intersect(edge, [u, v]);
            if length(common_vars) == 1
                condition_vars = setdiff(edge, common_vars);
                break;
            end
        end
    end
end

2.6 模型比较:compare_copula_models.m

function comparison = compare_copula_models(hierarchical_copula, rvine_model, data, params)
    % 比较分层Copula和R-Vine模型
    
    fprintf('  模型比较分析...\n');
    
    % 计算各种信息准则
    comparison = struct();
    
    % AIC比较
    comparison.aic_diff = hierarchical_copula.aic - rvine_model.aic;
    comparison.better_model_aic = comparison.aic_diff > 0 ? 'R-Vine' : 'Hierarchical Copula';
    
    % BIC比较
    n_params_hier = count_parameters(hierarchical_copula.parameters);
    n_params_rvine = count_rvine_parameters(rvine_model.pair_copulas);
    n_obs = size(data.uniform, 1);
    
    comparison.bic_hier = -2 * hierarchical_copula.loglikelihood + n_params_hier * log(n_obs);
    comparison.bic_rvine = -2 * rvine_model.loglikelihood + n_params_rvine * log(n_obs);
    comparison.bic_diff = comparison.bic_hier - comparison.bic_rvine;
    comparison.better_model_bic = comparison.bic_diff > 0 ? 'R-Vine' : 'Hierarchical Copula';
    
    % 似然比检验
    lr_stat = 2 * (rvine_model.loglikelihood - hierarchical_copula.loglikelihood);
    df = n_params_rvine - n_params_hier;
    p_value = 1 - chi2cdf(lr_stat, df);
    comparison.lr_test = struct('statistic', lr_stat, 'df', df, 'p_value', p_value, ...
                                'significant', p_value < 0.05);
    
    % 预测能力比较(使用交叉验证)
    comparison.cv_error = compare_predictive_ability(hierarchical_copula, rvine_model, data, params);
    
    fprintf('    AIC比较: 分层Copula=%.2f, R-Vine=%.2f, 差值=%.2f\n', ...
            hierarchical_copula.aic, rvine_model.aic, comparison.aic_diff);
    fprintf('    BIC比较: 分层Copula=%.2f, R-Vine=%.2f, 差值=%.2f\n', ...
            comparison.bic_hier, comparison.bic_rvine, comparison.bic_diff);
    fprintf('    似然比检验: χ²=%f, p-value=%f, %s\n', ...
            lr_stat, p_value, comparison.lr_test.significant ? '显著' : '不显著');
end

function cv_error = compare_predictive_ability(hierarchical_copula, rvine_model, data, params)
    % 比较预测能力(交叉验证)
    n_folds = 5;
    n_obs = size(data.uniform, 1);
    fold_size = floor(n_obs / n_folds);
    
    cv_errors_hier = zeros(n_folds, 1);
    cv_errors_rvine = zeros(n_folds, 1);
    
    for fold = 1:n_folds
        % 分割数据
        test_idx = (fold-1)*fold_size+1 : min(fold*fold_size, n_obs);
        train_idx = setdiff(1:n_obs, test_idx);
        
        % 训练模型
        hier_model = retrain_hierarchical_copula(data.uniform(train_idx, :), hierarchical_copula);
        rvine_model_train = retrain_rvine_model(data.uniform(train_idx, :), rvine_model);
        
        % 计算测试误差
        test_data = data.uniform(test_idx, :);
        cv_errors_hier(fold) = calculate_prediction_error(test_data, hier_model);
        cv_errors_rvine(fold) = calculate_prediction_error(test_data, rvine_model_train);
    end
    
    cv_error = struct('hierarchical', mean(cv_errors_hier), 'rvine', mean(cv_errors_rvine), ...
                      'difference', mean(cv_errors_hier) - mean(cv_errors_rvine));
end

2.7 依赖结构分析:analyze_dependency_structure.m

function dependency_analysis = analyze_dependency_structure(rvine_model, params)
    % 分析依赖结构
    
    fprintf('  依赖结构分析...\n');
    
    % 提取Pair-Copula参数
    pair_copulas = rvine_model.pair_copulas;
    fields = fieldnames(pair_copulas);
    
    % 计算依赖度量
    dependency_measures = struct();
    
    for i = 1:length(fields)
        field = fields{i};
        copula_info = pair_copulas.(field);
        
        % 计算Kendall's tau
        tau = calculate_kendalls_tau(copula_info.family, copula_info.params);
        
        % 计算尾部依赖系数
        lower_tail = calculate_lower_tail_dependence(copula_info.family, copula_info.params);
        upper_tail = calculate_upper_tail_dependence(copula_info.family, copula_info.params);
        
        dependency_measures.(field) = struct('tau', tau, 'lower_tail', lower_tail, ...
                                            'upper_tail', upper_tail, 'family', copula_info.family);
    end
    
    % 分析整体依赖结构
    dependency_analysis = struct();
    dependency_analysis.pair_copulas = dependency_measures;
    dependency_analysis.overall_tau = calculate_overall_kendalls_tau(dependency_measures);
    dependency_analysis.tail_dependence = analyze_tail_dependence(dependency_measures);
    dependency_analysis.dependency_clusters = identify_dependency_clusters(dependency_measures, params);
    
    fprintf('    平均Kendall''s tau: %.4f\n', dependency_analysis.overall_tau);
    fprintf('    尾部依赖分析完成\n');
end

function tau = calculate_kendalls_tau(family, params)
    % 计算Kendall's tau
    switch lower(family)
        case 'gaussian'
            rho = params.rho(1, 2);
            tau = 2 * asin(rho) / pi;
        case 't'
            rho = params.rho(1, 2);
            tau = 2 * asin(rho) / pi;
        case 'clayton'
            alpha = params.alpha;
            tau = alpha / (alpha + 2);
        case 'gumbel'
            alpha = params.alpha;
            tau = 1 - 1/alpha;
        case 'frank'
            alpha = params.alpha;
            % Frank Copula的tau需要数值积分
            tau = 1 - 4/alpha * (1 - (1-alpha)*exp(-alpha)/(1-exp(-alpha))/alpha);
        otherwise
            tau = 0.5; % 默认值
    end
end

function lower_tail = calculate_lower_tail_dependence(family, params)
    % 计算下尾依赖系数
    switch lower(family)
        case 'clayton'
            alpha = params.alpha;
            lower_tail = 2^(-1/alpha);
        case 'gumbel'
            lower_tail = 0; % Gumbel没有下尾依赖
        case 'frank'
            lower_tail = 0; % Frank没有下尾依赖
        otherwise
            lower_tail = 0;
    end
end

function upper_tail = calculate_upper_tail_dependence(family, params)
    % 计算上尾依赖系数
    switch lower(family)
        case 'clayton'
            upper_tail = 0; % Clayton没有上尾依赖
        case 'gumbel'
            alpha = params.alpha;
            upper_tail = 2 - 2^(1/alpha);
        case 'frank'
            upper_tail = 0; % Frank没有上尾依赖
        otherwise
            upper_tail = 0;
    end
end

2.8 风险度量计算:calculate_risk_measures.m

function risk_measures = calculate_risk_measures(hierarchical_copula, rvine_model, params)
    % 计算风险度量
    
    fprintf('  风险度量计算...\n');
    
    % 使用R-Vine模型进行蒙特卡洛模拟
    n_simulations = params.n_simulations;
    n_vars = size(rvine_model.structure.trees{1}, 2); % 变量数量
    
    % 生成模拟样本
    simulated_samples = simulate_rvine_samples(rvine_model, n_simulations, params);
    
    % 计算投资组合收益(等权重)
    portfolio_weights = ones(1, n_vars) / n_vars;
    portfolio_returns = simulated_samples * portfolio_weights';
    
    % 计算VaR和ES
    alpha = 1 - params.confidence_level;
    var = quantile(portfolio_returns, alpha);
    es = mean(portfolio_returns(portfolio_returns <= var));
    
    % 计算其他风险度量
    risk_measures = struct();
    risk_measures.var = var;
    risk_measures.es = es;
    risk_measures.std = std(portfolio_returns);
    risk_measures.skewness = skewness(portfolio_returns);
    risk_measures.kurtosis = kurtosis(portfolio_returns);
    
    % 计算边际风险贡献
    marginal_var_contrib = zeros(1, n_vars);
    for i = 1:n_vars
        partial_portfolio = portfolio_returns - simulated_samples(:, i) * portfolio_weights(i);
        partial_var = quantile(partial_portfolio, alpha);
        marginal_var_contrib(i) = (var - partial_var) * portfolio_weights(i);
    end
    risk_measures.marginal_var_contribution = marginal_var_contrib;
    
    fprintf('    VaR(%.0f%%): %.4f\n', params.confidence_level*100, var);
    fprintf('    ES(%.0f%%): %.4f\n', params.confidence_level*100, es);
    fprintf('    波动率: %.4f\n', risk_measures.std);
end

function simulated_samples = simulate_rvine_samples(rvine_model, n_simulations, params)
    % 使用R-Vine模型生成模拟样本
    n_vars = size(rvine_model.structure.trees{1}, 2);
    simulated_samples = zeros(n_simulations, n_vars);
    
    % 使用逆变换采样
    for sim = 1:n_simulations
        % 生成独立均匀分布样本
        u = rand(1, n_vars);
        
        % 通过R-Vine结构转换
        for tree_idx = 1:rvine_model.structure.n_trees
            tree_edges = rvine_model.structure.trees{tree_idx};
            n_edges = size(tree_edges, 1);
            
            for edge_idx = 1:n_edges
                edge_name = sprintf('tree%d_edge%d_%d_%d', tree_idx, edge_idx, ...
                                  tree_edges(edge_idx, 1), tree_edges(edge_idx, 2));
                
                if isfield(rvine_model.pair_copulas, edge_name)
                    copula_info = rvine_model.pair_copulas.(edge_name);
                    
                    % 应用Pair-Copula变换
                    u = apply_pair_copula_transform(u, copula_info, params);
                end
            end
        end
        
        simulated_samples(sim, :) = u;
    end
end

2.9 结果可视化:visualize_copula_results.m

function visualize_copula_results(hierarchical_copula, rvine_model, dependency_analysis, risk_measures, params)
    % 可视化Copula结果
    
    figure('Name', '分层Copula与Pair-Copula分析结果', 'Color', 'white', 'Position', [100, 100, 1600, 1000]);
    
    % 1. 分层结构图
    subplot(3,4,1);
    visualize_hierarchy(hierarchical_copula.hierarchy);
    title('分层Copula结构');
    
    % 2. R-Vine结构图
    subplot(3,4,2);
    visualize_rvine_structure(rvine_model.structure);
    title('R-Vine结构');
    
    % 3. 依赖矩阵热图
    subplot(3,4,3);
    dependency_matrix = extract_dependency_matrix(dependency_analysis);
    imagesc(dependency_matrix);
    colormap('hot');
    colorbar;
    title('依赖强度矩阵');
    xlabel('变量索引');
    ylabel('变量索引');
    
    % 4. 尾部依赖分析
    subplot(3,4,4);
    tail_dependence = extract_tail_dependence(dependency_analysis);
    bar(1:length(tail_dependence), tail_dependence, 'FaceColor', 'red');
    xlabel('Pair-Copula索引');
    ylabel('尾部依赖系数');
    title('尾部依赖分析');
    grid on;
    
    % 5. 模型比较
    subplot(3,4,5);
    model_names = {'分层Copula', 'R-Vine'};
    aic_values = [hierarchical_copula.aic, rvine_model.aic];
    bic_values = [hierarchical_copula.aic + 2*count_parameters(hierarchical_copula.parameters)*log(params.n_samples), ...
                  rvine_model.aic + 2*count_rvine_parameters(rvine_model.pair_copulas)*log(params.n_samples)];
    
    yyaxis left;
    plot(1:2, aic_values, 'b-o', 'LineWidth', 2, 'MarkerSize', 8);
    ylabel('AIC');
    
    yyaxis right;
    plot(1:2, bic_values, 'r-s', 'LineWidth', 2, 'MarkerSize', 8);
    ylabel('BIC');
    
    set(gca, 'XTick', 1:2, 'XTickLabel', model_names);
    title('模型比较 (AIC/BIC)');
    grid on;
    
    % 6. 风险度量仪表板
    subplot(3,4,6);
    gauge_chart(risk_measures.var, 'VaR', params.confidence_level*100);
    title('VaR风险值');
    
    subplot(3,4,7);
    gauge_chart(risk_measures.es, 'ES', params.confidence_level*100);
    title('ES期望损失');
    
    subplot(3,4,8);
    gauge_chart(risk_measures.std, '波动率', 0.3);
    title('投资组合波动率');
    
    % 7. 边际风险贡献
    subplot(3,4,9);
    marginal_contrib = risk_measures.marginal_var_contribution;
    barh(1:length(marginal_contrib), marginal_contrib, 'FaceColor', 'cyan');
    xlabel('边际VaR贡献');
    ylabel('资产索引');
    title('边际风险贡献');
    grid on;
    
    % 8. 模拟收益分布
    subplot(3,4,10);
    % 生成模拟样本(简化)
    n_sim = 10000;
    simulated_returns = randn(n_sim, 1) * risk_measures.std + mean(risk_measures.var);
    histogram(simulated_returns, 50, 'FaceColor', 'green', 'EdgeColor', 'black');
    xlabel('投资组合收益');
    ylabel('频数');
    title('模拟收益分布');
    grid on;
    
    % 9. 依赖结构网络图
    subplot(3,4,11);
    plot_dependency_network(dependency_analysis, params);
    title('依赖结构网络');
    
    % 10. 参数信息
    subplot(3,4,12); axis off;
    param_text = {
        sprintf('变量维度: %d', params.dim)
        sprintf('样本数量: %d', params.n_samples)
        sprintf('分层类型: %s', params.hierarchy_type)
        sprintf('Pair-Copula类型: %s', params.paircopula_type)
        sprintf('置信水平: %.0f%%', params.confidence_level*100)
        sprintf('模拟次数: %d', params.n_simulations)
        sprintf('分层CopulaAIC: %.2f', hierarchical_copula.aic)
        sprintf('R-Vine AIC: %.2f', rvine_model.aic)
    };
    text(0.1, 0.9, 'Copula系统参数:', 'FontSize', 12, 'FontWeight', 'bold');
    for i = 1:length(param_text)
        text(0.1, 0.9 - i*0.1, param_text{i}, 'FontSize', 10);
    end
    title('系统配置信息');
end

%% 可视化辅助函数
function visualize_hierarchy(hierarchy)
    % 可视化分层结构
    if iscell(hierarchy.levels{1})
        n_levels = length(hierarchy.levels);
        for level = 1:n_levels
            nodes = hierarchy.levels{level};
            y_pos = n_levels - level + 1;
            
            if iscell(nodes)
                for node_idx = 1:length(nodes)
                    node = nodes{node_idx};
                    if isvector(node)
                        x_positions = node;
                        plot(x_positions, y_pos * ones(size(x_positions)), 'bo', 'MarkerSize', 8, 'MarkerFaceColor', 'b');
                        hold on;
                    end
                end
            else
                x_positions = nodes;
                plot(x_positions, y_pos * ones(size(x_positions)), 'bo', 'MarkerSize', 8, 'MarkerFaceColor', 'b');
                hold on;
            end
        end
    end
    xlabel('变量索引');
    ylabel('层级');
    axis tight;
    grid on;
end

function visualize_rvine_structure(vine_structure)
    % 可视化R-Vine结构
    n_trees = vine_structure.n_trees;
    
    for tree_idx = 1:n_trees
        tree_edges = vine_structure.trees{tree_idx};
        y_pos = n_trees - tree_idx + 1;
        
        for edge_idx = 1:size(tree_edges, 1)
            u = tree_edges(edge_idx, 1);
            v = tree_edges(edge_idx, 2);
            plot([u, v], [y_pos, y_pos], 'r-', 'LineWidth', 2);
            hold on;
            plot(u, y_pos, 'ro', 'MarkerSize', 6, 'MarkerFaceColor', 'r');
            plot(v, y_pos, 'ro', 'MarkerSize', 6, 'MarkerFaceColor', 'r');
        end
    end
    
    xlabel('变量索引');
    ylabel('树层级');
    axis tight;
    grid on;
end

function gauge_chart(value, label, max_value)
    % 绘制仪表盘
    theta = linspace(0, pi, 100);
    r = 1;
    x = r * cos(theta);
    y = r * sin(theta);
    fill(x, y, [0.9, 0.9, 0.9], 'EdgeColor', 'black');
    hold on;
    
    % 指针
    pointer_angle = pi * (value / max_value);
    pointer_x = [0, 0.8 * cos(pointer_angle)];
    pointer_y = [0, 0.8 * sin(pointer_angle)];
    plot(pointer_x, pointer_y, 'r-', 'LineWidth', 3);
    
    % 中心圆
    rectangle('Position', [-0.1, -0.1, 0.2, 0.2], 'Curvature', [1, 1], 'FaceColor', 'red');
    
    axis equal;
    axis off;
    title(sprintf('%s\n%.4f', label, value));
end

三、扩展功能模块

3.1 动态Copula模型

function dynamic_copula = build_dynamic_copula(data, params)
    % 构建动态Copula模型(时变参数)
    
    % 滑动窗口估计
    window_size = 250; % 1年交易日
    n_obs = size(data.uniform, 1);
    
    dynamic_params = cell(n_obs - window_size + 1, 1);
    
    for t = window_size:n_obs
        window_data = data.uniform(t-window_size+1:t, :);
        
        % 估计时变Copula参数
        tv_params = estimate_time_varying_parameters(window_data, params);
        dynamic_params{t-window_size+1} = tv_params;
    end
    
    dynamic_copula = struct('window_size', window_size, 'parameters', dynamic_params);
end

3.2 极值Copula(Extreme Value Copula)

function ev_copula = build_extreme_value_copula(data, params)
    % 构建极值Copula(用于极端风险建模)
    
    % 提取极端事件(尾部数据)
    alpha = 0.05; % 极端事件阈值
    extreme_data = extract_extreme_events(data.uniform, alpha);
    
    % 估计极值Copula参数
    ev_families = {'galambos', 'husler-reiss', 't-ev'};
    best_ev_family = select_ev_copula_family(extreme_data, ev_families);
    
    % 估计参数
    ev_params = estimate_ev_copula_parameters(extreme_data, best_ev_family);
    
    ev_copula = struct('family', best_ev_family, 'parameters', ev_params, ...
                       'threshold', alpha, 'extreme_data', extreme_data);
end

参考代码 分层copula paircopula的计算 www.youwenfan.com/contentcsu/60175.html

四、建议

4.1 模型选择

场景 推荐模型 理由
高维数据(>10) R-Vine 灵活性高,能捕捉复杂依赖
分层结构明显 分层Copula 解释性强,计算效率高
尾部风险重要 极值Copula 专门建模极端事件
实时应用 分层Copula 计算速度快

4.2 参数估计

% 1. 使用稳健估计方法
params.optimization_method = 'itau'; % 秩相关估计,对异常值稳健

% 2. 正则化防止过拟合
lambda = 0.01; % L2正则化参数

% 3. 交叉验证选择模型
cv_errors = cross_validate_copula_models(data, params);
best_model = select_best_model(cv_errors);

 

专注于matlab/simulink,电子电路,编程