如何用rvinecopulib拟合Copula并生成原单位随机样本?
问题
我有一个高维非多元正态数据集,使用rvinecopulib拟合Copula模型后,通过rvinecop()生成了归一化的随机样本(基于伪观测转换后的均匀分布数据),但不知道如何将这些样本转换回克、毫米等原始单位,想确认是否需要用到边缘分布?
以下是基于palmer penguins数据集的示例代码:
# copula pens library(tidyverse) library(palmerpenguins) library(rvinecopulib) data("penguins") dat <- penguins %>% na.omit() %>% filter(species=="Adelie") %>% select(body_mass_g,bill_depth_mm,flipper_length_mm) u <- pseudo_obs(dat) # 转换为归一化秩数据 # 拟合并选择Copula模型结构、族和参数 fit <- vinecop(u) fit summary(fit) contour(fit) # 从模型生成样本 uSim <- data.frame(rvinecop(n=200,fit)) summary(uSim) # 样本是归一化形式,需要转回原始单位
解决方案
是的,必须用到原始数据的边缘经验分布来完成逆变换,才能将生成的均匀分布样本转回原始单位。
原理:pseudo_obs()函数本质是将原始数据通过经验分布函数转换为[0,1]区间的均匀分布伪观测值,因此要还原原始单位,需要对生成的样本应用经验分布的逆变换(即分位数函数)。
修改后的完整代码如下:
# copula pens library(tidyverse) library(palmerpenguins) library(rvinecopulib) data("penguins") dat <- penguins %>% na.omit() %>% filter(species=="Adelie") %>% select(body_mass_g,bill_depth_mm,flipper_length_mm) u <- pseudo_obs(dat) # 转换为归一化秩数据 # 拟合并选择Copula模型结构、族和参数 fit <- vinecop(u) # 从模型生成样本 uSim <- data.frame(rvinecop(n=200,fit)) # 定义经验分布逆变换函数:对每个变量,用原始数据的经验分位数还原 inv_transform <- function(col_sim, col_original) { # 经验分布的逆变换,即分位数函数,与pseudo_obs的分位数类型保持一致 quantile(col_original, probs = col_sim, type = 1) } # 对每个样本列应用逆变换,还原为原始单位 sim_original <- pmap_dfc(list(uSim, dat), inv_transform) # 设置列名与原始数据一致 colnames(sim_original) <- colnames(dat) summary(sim_original) # 现在样本是原始单位(克、毫米)
关键说明
pseudo_obs()默认使用type=1的分位数计算伪观测,因此逆变换时quantile()也要指定type=1,保证转换逻辑的一致性。- 这里使用经验边缘分布是因为没有对原始数据的边缘分布做参数化假设;如果之前有拟合参数化边缘分布(如正态、对数正态等),也可以用对应分布的分位数逆函数(如
qnorm()、qlnorm()等)完成转换。
内容的提问来源于stack exchange,提问作者user111024
相关产品推荐
相关产品推荐

