R语言实现 Copula 建模依赖性案例分析报告

copula是将多变量分布函数与其边际分布函数耦合的函数,通常称为边缘或简单的边缘。Copula是建模和模拟相关随机变量的绝佳工具。

Copula的主要吸引力在于,通过使用它们,您可以分别对相关结构和边缘(即每个随机变量的分布)进行建模。这可能是一个优点,因为对于某些边缘组合,没有内置函数来生成所需的多变量分布。例如,在R中,很容易从多元正态分布中生成随机样本,但是对于分别其边缘分别为Beta,Gamma和Student的分布来说,这样做并不容易。
此外,正如您可以通过谷歌搜索copula看到的那样,有各种各样的模型提供了一组非常不同且可定制的相关结构,可以很容易地适应观察到的数据并用于模拟。这种多样的选择是我最喜欢copulas的事情之一。

在这篇文章中,我们将展示如何使用copula包在R中使用copula,然后我们尝试提供一个简单的应用示例。

copulas如何工作 

但首先,让我们试着了解copula的实际工作方式。
我们使用包n给出协方差矩阵,从3个随机变量的多元正态分布中生成样本。sigmaMASS

图书馆(MASS)
set.seed(100)

m < - 3
n < - 2000
西格玛< - 矩阵(c(1,0.4,0.2,
0.4,1,-0.8,
0.2,-0.8,1),
nrow = 3)
z < - mvrnorm(n,mu = rep(0,m),Sigma = sigma,empirical = T)

现在我们使用cor()和配对图检查样本相关性。
我们将设置method='spearman'为使用 而不是函数中的'pearson'方法cor()(这在我们的例子中并不是绝对必要的,因为我们将使用椭圆形copula,如果你使用非椭圆形copula,你可能想要使用Spearman的Rho或Kendall的Tau)。

库(斗志)
心病(Z,方法= '斯皮尔曼')
pairs.panels(Z)

[,1] [,2] [,3]
[1,] 1.0000000 0.3812244 0.1937548
[2,] 0.3812244 1.0000000 -0.7890814
[3,] 0.1937548 -0.7890814 1.0000000

输出和配对图显示我们的样本确实具有完全预期的相关结构。
Rplot

你< -  pnorm(z)
pairs.panels(U)

这是包含在中的新随机变量的配对图u。请注意,每个分布在[0,1]区间内是均匀的。还要注意,相关性相同,实际上,我们应用的变换并没有改变随机变量之间的相关结构。基本上我们只留下通常被称为依赖结构的东西
Rplot01
通过使用rgl库,我们可以绘制矢量的漂亮3D表示u。这非常适合演示目的,您可以轻松地围绕图形旋转,以防您想要检查不同的视角:  只需单击图片并拖动鼠标即可。

库(RGL)
PLOT3D格式(U [1]中,u [2],U [1,3],PCH = 20,列= 'navyblue')

 
浏览图片1
现在,作为最后一步,我们只需要选择边距并应用它们u。我选择了边缘为Gamma,Beta和Student,并使用下面指定的参数进行分配。

x1 < -  qgamma(u [,1],shape = 2,scale = 1)
x2 < - qbeta(u [,2],2,2)
x3 < - qt(u [,3],df = 5)
PLOT3D格式(X1,X2,X3,PCH = 20,列= '蓝')

下面是我们模拟数据的3D图。花几秒钟检查一下。可以肯定的是,这是一个非常简单的依赖结构,它以非常简单的方式生成并且步骤非常少。

Immagine 2
值得注意的是,从多变量正态样本开始,我们构建了一个具有所需和固定依赖结构的样本,基本上是任意边缘

df < -  cbind(x1,x2,x3)
pairs.panels(DF)
心病(DF,甲基= '斯皮尔曼')

x1 x2 x3
x1 1.0000000 0.3812244 0.1937548
x2 0.3812244 1.0000000 -0.7890814
x3 0.1937548 -0.7890814 1.0000000

这是随机变量的配对图:

Rplot02
我再次强调,我选择了完全随意的边缘。只要它是一个连续的函数,我就可以选择任何边际。

使用copula包

上面执行的整个过程可以更有效,简洁地完成,并且完全由copula包装进行一些额外的关注。让我们使用copula复制上面的过程。

库(系动词)
set.seed(100)
myCop < - normalCopula(param = c(0.4,0.2,-0.8),dim = 3,dispstr =“un”)
myMvd < - mvdc(copula = myCop,margin = c(“gamma”,“beta”,“t”),
paramMargins = list(list(shape = 2,scale = 1),
列表(shape1 = 2,shape2 = 2),
列表(df = 5)))

现在我们已经通过copula(普通copula)指定了依赖结构并设置了边缘,该mvdc()函数生成了所需的分布。然后我们可以使用该rmvdc()函数生成随机样本。

Z2 < -  rmvdc(myMvd,2000)
colnames(Z2)< - c(“x1”,“x2”,“x3”)
pairs.panels(Z2)

模拟数据当然非常接近之前模拟的数据,并显示在下面的配对图中:

Rplot03

一个简单的应用示例

现在为现实世界的例子。我们将拟合两个股票的回报,并尝试使用copula模拟回报。我已经清理了两只股票的数据并计算了回报,你可以下载.csv格式的数据  。请注意,数据可能不是您在Google财经上可以找到的数据,因为我做了一些数据清理并删除了一些异常值而没有多想,主要是因为这是另一个应用程序的玩具示例。
让我们在R中加载回报

cree < -  read.csv('cree_r.csv',header = F)$ V2
yahoo < - read.csv('yahoo_r.csv',header = F)$ V2

在直接进入copula拟合过程之前,让我们检查两个股票收益之间的相关性并绘制回归线:

情节(CREE,雅虎,PCH = '')
abline(LM(雅虎〜CREE),山口= '红',LWD = 1)
心病(CREE,雅虎,方法= '斯皮尔曼')

[1] 0.4023584

我们可以看到一个非常温和的正相关 :

Rplot06

在上面的第一个例子中,我选择了一个普通的copula模型而没有太多思考,但是,当将这些模型应用于实际数据时,应该仔细考虑哪些更适合数据。例如,许多copula更适合建模非对称相关,其他强调尾部相关性等等。我对股票回报的猜测是,t-copula应该没问题,但是猜测肯定是不够的。幸运的是,该VineCopula软件包提供了一个很好的功能,告诉我们应该使用什么copula。本质上,VineCopula库允许我们通过函数使用BIC和AIC执行copula选择BiCopSelect()

库(VineCopula)
你< - pobs(as.matrix(cbind(cree,yahoo)))[,1]
v < - pobs(as.matrix(cbind(cree,yahoo)))[,2]
selectedCopula < - BiCopSelect(u,v,familyset = NA)
selectedCopula

$家庭
[1] 2

$ PAR
[1] 0.4356302

$ PAR2
[1] 3.844534

请注意,我使用pobs()函数将伪观察结果输入到选择算法中。伪观测值是[0,1]区间内的观测值。
拟合算法确实选择了t-copula(在$family参考中编码为2 )并为我们估计了参数。通过键入,?BiCopSelect()您实际上可以看到每个copula的编码。
让我们尝试使用copula包装拟合建议的模型,并仔细检查参数拟合。

t.cop < -  tCopula(dim = 2)
set.seed(500)
m < - pobs(as.matrix(cbind(cree,yahoo)))
适合< - fitCopula(t.cop,m,method ='ml')
COEF(FIT)

rho.1 df
0.43563 3.84453

很高兴看到拟合的copula的参数与函数建议的参数相同BiCopSelect()。我们来看看我们刚估计的copula的密度

rho < -  coef(fit)[1]
df < - coef(fit)[2]
persp(tCopula(暗= 2,ρ-,DF = DF),dCopula)

Rplot18
现在我们只需要建立Copula并从中抽取3965个随机样本。

你< -  rCopula(3965,tCopula(dim = 2,rho,df = df))
情节(U [1]中,u [2],PCH = ' 'COL =' 蓝')
心病(U,方法= '斯皮尔曼')

[,1] [,2]
[1,] 1.0000000 0.3972454
[2,] 0.3972454 1.0000000

这是载体中包含的样本的图u
Rplot05

来自copula的随机样本看起来有点接近独立情况,但这很好,因为回报之间的相关性很低。请注意,生成的样本与数据具有相同的相关性。
t-copula强调极端结果:它通常适用于在极值(分布的尾部)中存在高度相关性的建模现象。
还要注意它是对称的,这可能是我们的应用程序的问题,但是我们将忽略这一点。

现在我们正面临着困难:对边缘进行建模。为简单起见,我们将假设正态分布的回报,尽管众所周知它远非合理的假设。因此,我们估计边际的参数

cree_mu < -  mean(cree)
cree_sd < - sd(cree)
yahoo_mu < - 意味着(雅虎)
yahoo_sd < - sd(雅虎)

让我们根据直方图绘制配件,以便直观地了解我们正在做的事情:

hist(cree,breaks = 80,main ='Cree returns',freq = F,density = 30,col ='cyan',ylim = c(0,20),xlim = c(-0.2,0.3))
线(SEQ(-0.5,0.5,0.01),dnorm(SEQ(-0.5,0.5,0.01),cree_mu,cree_sd),山口= '红',LWD = 2)
传奇('topright',c('Fitted normal'),col = c('red'),lwd = 2)
hist(yahoo,breaks = 80,main ='Yahoo returns',density = 30,col ='cyan',freq = F,ylim = c(0,20),xlim = c(-0.2,0.2))
线(SEQ(-0.5,0.5,0.01),dnorm(SEQ(-0.5,0.5,0.01),yahoo_mu,yahoo_sd),山口= '红',LWD = 2)
传奇('topright',c('Fitted normal'),col = c('red'),lwd = 2)

两个直方图显示如下

Rplot11
Rplot12
不要让漂亮的图表欺骗你,在回报分布的假设下,我们忽略了位于分布尾部的一些极端回报,但在这个例子中我们对联合行为感兴趣,所以我们就是这样即将分析。

现在我们在函数中应用copula,mvdc()然后用于rmvdc()从生成的多变量分布中获取模拟观测值。最后,我们将模拟结果与原始数据进行比较。

copula_dist < -  mvdc(copula = tCopula(rho,dim = 2,df = df),margin = c(“norm”,“norm”),
paramMargins = list(list(mean = cree_mu,sd = cree_sd),
list(mean = yahoo_mu,sd = yahoo_sd)))
sim < - rmvdc(copula_dist,3965)

好,现在我们有模拟数据,让我们进行视觉比较

情节(CREE,雅虎,主要= '返回')
点(SIM [1],SIM [2],COL = '红')
图例( 'bottomright',C( '观察', '模拟'),列= C( '黑', '红'),PCH = 21)

这是在假设正常边缘和依赖结构的t-copula的情况下数据的最终散点图:
Rplot13
正如您所看到的,t-copula导致结果接近实际观察结果,尽管极端回报比实际数据少,我们错过了一些最极端的结果。如果我们对与这些库存相关的风险进行建模感兴趣,那么这将是一个主要的红旗,需要通过进一步的模型校准来解决。

由于此示例的目的仅仅是为了展示如何使用真实数据拟合copula并生成随机观察,我们将在此处停止。

正如好奇心让我向您展示如何通过调整dft-copula中的参数来改变copula中的模拟值。
让我们尝试df=1df=8

set.seed(4258)
copula_dist < - mvdc(copula = tCopula(rho,dim = 2,df = 1),margin = c(“norm”,“norm”),
paramMargins = list(list(mean = cree_mu,sd = cree_sd),
list(mean = yahoo_mu,sd = yahoo_sd)))
sim < - rmvdc(copula_dist,3965)
情节(CREE,雅虎,主要= '返回')
点(SIM [1],SIM [2],COL = '红')
legend('bottomright',c('Observed','Simulated df = 1'),col = c('black','red'),pch = 21)
心病(SIM [1],SIM [2],方法= '斯皮尔曼')

copula_dist < - mvdc(copula = tCopula(rho,dim = 2,df = 8),margin = c(“norm”,“norm”),
paramMargins = list(list(mean = cree_mu,sd = cree_sd),
list(mean = yahoo_mu,sd = yahoo_sd)))
sim < - rmvdc(copula_dist,3965)
情节(CREE,雅虎,主要= '返回')
点(SIM [1],SIM [2],COL = '红')
legend('bottomright',c('Observed','Simulated df = 8'),col = c('black','red'),pch = 21)
心病(SIM [1],SIM [2],方法= '斯皮尔曼')

[1] 0.3929509
[1] 0.3911127

注意虽然Spearman的Rho类似,但我们获得的依赖结构有多么不同。
显然,该参数df对于确定分布的形状非常重要。随着df增加,t-copula倾向于高斯copula。

Rplot16
Rplot17

 

有问题吗?联系我们!

 

大数据部落 -中国专业的第三方数据服务提供商,提供定制化的一站式数据挖掘和统计分析咨询服务

统计分析和数据挖掘咨询服务:y0.cn/teradat(咨询服务请联系官网客服

点击这里给我发消息​QQ:3025393450

【服务场景】  

科研项目; 公司项目外包;线上线下一对一培训;数据采集;学术研究;报告撰写;市场调查。

【大数据部落】提供定制化的一站式数据挖掘和统计分析咨询服务

【大数据部落】大数据部落提供定制化的一站式数据挖掘和统计分析咨询服务

猜你喜欢

转载自www.cnblogs.com/tecdat/p/10913638.html