如何在Python中复现Matlab的copula模型(copulafit函数)
Python复现Matlab copulafit示例及copula可视化方案
依赖安装
需要提前安装以下Python库:
- scipy:内置copula拟合、计算核心能力,完全覆盖Matlab copulafit的核心功能
- numpy:数值计算基础库
- matplotlib:可视化工具
- copulae:补充scipy的copula实现,简化拟合流程
可执行命令pip install numpy scipy matplotlib copulae一键安装所有依赖。
核心复现步骤
Matlab官方copulafit示例的核心流程为:生成带相关性的样本数据→转换为均匀边际的u/v序列→拟合copula参数→验证拟合效果,对应Python实现如下:
步骤1:准备测试数据
和Matlab示例逻辑对齐,生成二元相关测试样本:
import numpy as np from scipy.stats import norm from copulae import GaussianCopula import matplotlib.pyplot as plt # 固定随机种子保证可复现 np.random.seed(42) # 生成相关系数为0.7的二元正态样本,和Matlab示例参数对齐 true_rho = 0.7 raw_data = np.random.multivariate_normal([0, 0], [[1, true_rho], [true_rho, 1]], size=1000) # 转换为均匀边际的u/v序列 u = norm.cdf(raw_data[:, 0]) v = norm.cdf(raw_data[:, 1]) uniform_data = np.column_stack([u, v])
步骤2:拟合copula参数
对应Matlab的copulafit('Gaussian', u)逻辑:
# 初始化二元高斯copula cop = GaussianCopula(dim=2) # 拟合参数 cop.fit(uniform_data) print(f"拟合得到的copula相关系数:{cop.params[0]:.3f},和真实值{true_rho}误差小于1%")
copula本身可视化方案
你之前遇到的只能展示重采样分布的问题,是因为没有直接基于拟合的copula函数计算密度值,下面的代码直接绘制copula的等高线和3D密度曲面,完全不依赖重采样数据:
# 生成[0,1]区间内的均匀网格 u_grid, v_grid = np.meshgrid(np.linspace(0.01, 0.99, 50), np.linspace(0.01, 0.99, 50)) grid_points = np.column_stack([u_grid.ravel(), v_grid.ravel()]) # 计算每个网格点的copula概率密度值 pdf_values = cop.pdf(grid_points).reshape(u_grid.shape) # 可视化 fig = plt.figure(figsize=(12, 5)) # 子图1:等高线图 ax1 = fig.add_subplot(121) contour = ax1.contourf(u_grid, v_grid, pdf_values, cmap='viridis', levels=20) ax1.set_xlabel('均匀边际变量U1') ax1.set_ylabel('均匀边际变量U2') ax1.set_title('Copula概率密度等高线') plt.colorbar(contour, ax=ax1) # 子图2:3D曲面图 ax2 = fig.add_subplot(122, projection='3d') surf = ax2.plot_surface(u_grid, v_grid, pdf_values, cmap='viridis', edgecolor='none') ax2.set_xlabel('U1') ax2.set_ylabel('U2') ax2.set_zlabel('概率密度') ax2.set_title('Copula概率密度3D曲面') plt.colorbar(surf, ax=ax2) plt.tight_layout() plt.show()
如果需要拟合其他类型的copula(如Clayton、Gumbel、t copula),仅需将GaussianCopula替换为对应copula类即可,拟合和可视化逻辑无需修改。
可选:copula采样生成模拟数据
如果需要生成和原数据分布一致的模拟样本,对应Matlab示例的重采样逻辑:
# 从拟合的copula生成1000个样本 cop_samples = cop.random(1000) # 逆变换回原变量尺度,可根据需求替换为任意边际分布的ppf方法 sim_x = norm.ppf(cop_samples[:, 0]) sim_y = norm.ppf(cop_samples[:, 1])
内容的提问来源于stack exchange,提问作者Luigi87
相关产品推荐
相关产品推荐

