可以转载,禁止修改。转载请注明作者和原文链接。
先用人话来描述一下这个问题:有两个收益不固定的投资项目,如何将一笔固定的金额分开投资,才能使总投资风险最小?
再用数学语言来描述一下这个问题,对于两个收益分别为X和Y的金融资产,X、Y为随机变量,把比例为α的金额投到X上,把剩下比例为1-α的金额投到Y中,使Var(αX+(1-α)Y)最小。根据方差的性质、协方差的定义以及极值的导数意义进行转化并求导,可以很easy地得到:
其中
如果知道总体X、Y的分布,那么可以直接求出α,但事实上往往不知道,只有样本。这个时候就需要根据样本来估计α,但α的估计值真的靠谱么?显然只给出一个数字是不行的。如果α的估计值自身都很不稳定,那就这种计算方法也就不靠谱了。
这里介绍一种重抽样方法:自助法(bootstrap)
。这里直接引用CSDN上老子今晚不加班
的《Bootstrap 自助法》中的定义:
在统计学中,自助法(BootstrapMethod,Bootstrapping或自助抽样法)可以指任何一种有放回的均匀抽样,也就是说,每当选中一个样本,它等可能地被再次选中并被再次添加到训练集中。自助法能对采样估计的准确性(标准误差、置信区间和偏差)进行比较好的估计,它基本上能够对任何采样分布的统计量进行估计。
Bootstrap有两种形式:非参数bootstrap和参数化的bootstrap,但基本思想都是模拟。参数化的bootstrap假设总体的分布已知或总体的分布形式已知,可以由样本估计出分布参数,再从参数化的分布中进行再采样,类似于MC。非参数化的bootstrap是从样本中再抽样,而不是从分布函数中进行再抽样。
总而言之,bootstrap是一种可放回式抽样法,当进行大量这种抽样时,可以对估计量的统计量(方差、标准差、标准误差、置信区间等)有一个较为稳定、准确的估计。
这里以R的 ISLR
包中的 Portfolio
数据集为例,以之为样本,进行自助法重抽样,观察根据样本重抽样计算的α的估计量。
老规矩,先看一下数据集:
> library(ISLR)
> str(Portfolio)
‘data.frame‘: 100 obs. of 2 variables:
$ X: num -0.895 -1.562 -0.417 1.044 -0.316 ...
$ Y: num -0.235 -0.885 0.272 -0.734 0.842 ...
可见数据框100行,两列X、Y都是数值型。
先计算一下根据样本中所有的观测数据求得的α。
> # 求α的函数
> alpha=function(x,y){
+ vx=var(x)
+ vy=var(y)
+ cxy=cov(x,y)
+ (vy-cxy)/(vx+vy-2*cxy)
+ }
> alpha(Portfolio$X,Portfolio$Y)
[1] 0.5758321
再来求α的估计值。
> # 求α估计值的函数
> alpha.fn=function(data, index){
+ with(data[index,],alpha(X,Y))
+ }
> # 检查一下是否与上面结果一致
> alpha.fn(Portfolio,1:100)
[1] 0.5758321
> # 结果一致
下面进行重抽样。
> # 设定随机数种子
> set.seed(1)
> # 可放回抽100个样本
> alpha.fn (Portfolio,sample(1:100,100,replace=TRUE))
[1] 0.5963833
> # 可放回抽1000个样本
> alpha.fn (Portfolio,sample(1:100,100,replace=TRUE))
[1] 0.5796283
可见,当抽样容量更大时,α的估计值与实际值更接近。
不过当然不必自定义函数,自己去抽样计算,R肯定有自带的bootstrap方法的函数。
> boot.out=boot(Portfolio,alpha.fn,R=1000)
> boot.out
ORDINARY NONPARAMETRIC BOOTSTRAP
Call:
boot(data = Portfolio, statistic = alpha.fn, R = 1000)
Bootstrap Statistics :
original bias std. error
t1* 0.5758321 4.879587e-06 0.08872272
boot()
函数输入数据集,欲计算的估计量,以及抽样次数就可以进行bootstrap抽样。从结果上来看,对于原始数据,样本α估计值为0.5758(由于随机性,与上面的结果略有差异),标准误为0.0887。
还可以对估计量进行可视化,观察α估计量的分布。
> plot(boot.out)
可见α估计量正态性良好。
bootci()
函数可用来求估计量的置信区间。
> boot.ci(boot.out)
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 1000 bootstrap replicates
CALL :
boot.ci(boot.out = boot.out)
Intervals :
Level Normal Basic
95% ( 0.4019, 0.7497 ) ( 0.3909, 0.7440 )
Level Percentile BCa
95% ( 0.4076, 0.7607 ) ( 0.4107, 0.7617 )
Calculations and Intervals on Original Scale
Warning message:
In boot.ci(boot.out) : bootstrap variances needed for studentized intervals
结果中的4种置信区间是根据不同的方法计算出来的,差别不大,按需取之即可。
这下不仅能给出α的估计值,还能给出标准误和置信区间,有理有据,令人信服。
参考文献
Gareth James et al. An Introduction to Statistical Learning.
?