- Python量化投资:技术、模型与策略
- 赵志强 刘志伟
- 1587字
- 2021-04-04 11:20:20
5.2 连续随机变量分布
SciPy包含了大量的处理连续随机变量的函数,每种函数都位于与其对应的分布类中。每个类都有对应的方法来生成随机数,从而计算PDF、CDF,使用MLE进行参数估计,以及矩估计等。相应的方法将在下文中详细讲解,其中,dist代表了SciPy中相应的分布名称,每种分布除了自身特殊的输入变量之外,还包含三种常用的参数,具体说明如下。
·*args:表示每个分布定义所需的参数。例如,使用F分布的时候,需要两个参数。第一个参数是分子自由度。第二个参数是分母自由度。
·loc:表示位置参数,用于决定分布的中心位置。
·scale:表示比例参数,用于决定分布的缩放比例。例如,假设z是标准的正态分布,那么s×x就是一个缩放s倍的标准正态分布。
5.2.1 分布的基本特征
SciPy能够生成各种满足不同分布的随机数。
1.dist.rvs
dist.rvs是伪随机数生成函数,一般调用方法为dist.rvs(*args,loc=0,scale=1,size=size)。其中,size是一个n维数据,决定了所生成数组的大小。示例代码如下:
from scipy import stats a = stats.chi2(10).rvs(1000) plt.hist(a,bins = 50)
运行结果如图5-8所示。
图 5-8
我们来考察一下分布的一些基本特征。
2.dist.pdf
dist.pdf是指对一组数据估计出来的概率密度函数,一般调用方法为dist.pdf(x,*args,loc=0,scale=1)。其中,x是用来进行估计的数组。示例代码如下:
stats.norm(0,1).pdf(0) Out[49]: 0.3989422804014327
3.dist.logpdf
dist.logpdf是指对一组数据估计出来的对数概率密度函数,一般调用方法为dist.logpdf(x,*args,loc=0,scale=1),其中,x是用来进行估计的数组。示例代码如下:
stats.norm(0,1).logpdf(0) Out[50]: -0.9189385332046727
4.dist.cdf
dist.cdf是指对一组数据估计出来的累积分布函数,一般调用方法为dist.cdf(x,*args,loc=0,scale=1),其中,x是用来进行估计的数组。示例代码如下:
stats.norm(0,1).cdf(2) Out[54]: 0.9772498680518208
5.dist.ppf
dist.ppf是指对于一组范围为0到1的数据,估计出来的累积分布函数的反函数,一般调用方法为dist.ppf(p,*args,loc=0,scale=1),其中,p是所有元素均为0到1之间数据的数组。示例代码如下:
stats.norm(0,1).ppf(0.618) Out[55]: 0.30023225938072184
6.dist.fit
对于一组数据,使用最大似然法估计出其形状、位置及比例参数,一般调用方法为dist.fit(data,*args,f?loc=0,fscale=1),其中,data是用来估计参数的数据;floc用于强制规定location的取值;fscale用于强制规定scale的取值。在使用最大似然估计的时候,如果分布没有location和scale,那么一般有必要强制规定一个取值。
下面来看一个示例,首先生成10000个自由度为10的卡方分布模拟数据,代码如下:
a = stats.chi2(10).rvs(10000)
然后利用MLE进行拟合,代码如下:
stats.chi2.fit(a) Out[58]: (10.258104233623369, -0.11014565203039026, 0.9850494177711357)
在获得的结果当中,数组的第一个数为卡方分布的自由度估计,第二个第三个为中心值和scale。
7.dist.mean
dist.mean用于返回分布的均值,一般调用方法为dist.mean(*args,loc=0,scale=1)。示例代码如下:
stats.beta(1,2).mean() Out[60]: 0.3333333333333333
8.dist.median
dist.median用于返回分布的中位数,一般调用方法为dist.mean(*args,loc=0,scale=1)。示例代码如下:
stats.chi2(10).median() Out[61]: 9.34181776559197
9.dist.var
dist.var用于返回分布的方差,一般调用方法为dist.var(*args,loc=0,scale=1)。示例代码如下:
stats.chi2(10).var() Out[73]: 20.0
10.dist.std
dist.std用于返回分布的标准差,一般调用方法为dist.std(*args,loc=0,scale=1)。示例代码如下:
stats.chi2(10).std() Out[74]: 4.47213595499958
5.2.2 衍生特征
1.偏度
skewness代表分布的偏度特征,偏度描述的是一个分布的“不对称性”,其计算公式为:
为了理解不对称性,我们先来看几个对称分布,示例代码如下:
import seaborn as sns import numpy as np x = np.random.normal(size=10000) sns.distplot(x) Out[65]: <matplotlib.axes._subplots.AxesSubplot at 0x277cbf32908>
画出相应的图,如图5-9所示。
图 5-9
可以看到,标准正态分布是以y轴为中心对称的,并且分布的平均数与标准差分别为0和1。很显然,对于标准正态分布而言,分布的偏度等于其三阶矩,我们用Scipy的dist.moment函数即可获得其偏度。
返回分布的n阶中心矩,一般的调用方法为dist.moment(r,*args),其中,r是需要计算的矩的阶数。示例代码如下:
stats.norm().moment(3) Out[66]: 0.0
再来看另外一个例子,卡方分布,示例代码如下:
import seaborn as sns import numpy as np x = stats.chi2(10).rvs(100000) sns.distplot(x) Out[67]: <matplotlib.axes._subplots.AxesSubplot at 0x277ca44add8>
画出相应的图,如图5-10所示。
图 5-10
很明显,分布并不是中心对称的。
下面来计算一下其偏度,示例代码如下:
stats.skew(stats.chi2(10).rvs(100000)) Out[71]: 0.8891063018810491
2.kurtosis峰度
峰度描述的是分布函数在平均值位置的取值高低的统计量。峰值高低是相对于标准正态分布的平均值而言的。一般定义正态分布的峰度为0。为了满足这一定义,计算峰度的公式如下:
感兴趣的读者可以计算一下标准正态分布的峰度(提示:利用moment generating function可以很轻易地得出标准正态分布的各阶中心矩)。
下面来看一个典型的比正态分布峰值相对更高的分布:拉普拉斯分布(Laplace Distribution)。示例代码如下:
x = stats.laplace(loc = 0, scale = 1).rvs(10000) sns.distplot(x)
画出相应的图,如图5-11所示。
图 5-11
下面就来生成大量的随机数,来估计一下在相同loc和scale的情况下,拉普拉斯分布与正态分布的峰值,示例代码如下:
x = stats.laplace(loc = 0, scale = 1).rvs(10000) stats.kurtosis(x) Out[85]: 3.245024800904149 y = stats.norm(loc = 0, scale = 1).rvs(10000) stats.kurtosis(y) Out[86]: -0.00889987923437019