[关闭]
@Channelchan 2018-09-30T12:13:36.000000Z 字数 5370 阅读 78719

如何做金融数据统计?

目录

  1. 快读检验一列数是否是正态分布。
  2. 偏度和峰度.
  3. scipy简要介绍
  4. scipy.stats.ProbPlot
  5. 从ptobplott中得到一些信息
  6. 从箱形图中得到一些信息

1.快速检验正态分布

正态分布是最常见的分布形式之一,在开始分析数据时快速判断分布的形式有时能节省很多功夫。

JarqueBera检验可以帮助我迅速判断一个分布是否属于正态分布,JarqueBera检验返回一个P-value,P-Value越小代表越不可能是正态分布。这里我取0.05作为阈值.

假设回报率是满足正态分布,然而当p_value<0.05则拒绝原假设,该股票回报率不为正态分布。

用t检验600036股票收益率均值是否为0,假设平均收益率为0,然而当p_value>0.05则无法拒绝原假设,该股票平均收益率为0。

  1. import tushare as ts
  2. import pandas as pd
  3. from statsmodels.stats.stattools import jarque_bera
  4. from scipy import stats
  5. import numpy as np
  6. import matplotlib.pyplot as plt
  7. data = ts.get_k_data('600036', start='2016-01-01', end='2016-12-31', ktype='D',autype='qfq')
  8. data.index = pd.to_datetime(data['date'],format='%Y-%m-%d')
  9. data['percentage']=data['close'].pct_change()
  10. returns = data['percentage'][1:]
  11. _, pvalue, _, _ = jarque_bera(returns)
  12. if pvalue > 0.05:
  13. print ('判断样本分布服从正态分布')
  14. else:
  15. print ('判断样本分布不服从正态分布')
判断样本分布不服从正态分布

另一个人们关心的属性就是收益率的均值,t_test可以帮助我们快速判断一组数据的均值位置,单样本t_test可以传入2个参数,第一个是待检验的数据,第二个是原假设均值。比如下面我第二个参数传入0,检验的就是样本均值为0的概率。

  1. t_test = stats.ttest_1samp(returns, 0)
  2. if t_test.pvalue > 0.05:
  3. print ('判断样本均值为0')
  4. else:
  5. print ('判断样本均值不为0')
判断样本均值为0

2.偏度与峰度?

除了人们最关心的均值和方差,这里我再介绍两个统计量,偏度和峰度。

image.png-0.5kB表示随机变量X的均值和方差。

偏度(Skewness)

image.png-2.4kB

偏度用于描述一个分布是否左右对称,一个左右对称的分布偏度(skewness)的值为 0.

正倾斜偏度分布意味 mean > median > mode。

负倾斜偏度分布意味 mean < median < mode。

正峰度和负峰度的直观举例

![pearson-mode-skewness.jpg](attachment:pearson-mode-skewness.jpg)

反过来讲,一个偏度为0的分布就是左右对称的吗?在大多数情况下这是正确的,也是符合直觉的。但如果你是一个喜欢刨根问底的有着浓厚数学基因的人,好吧,确实存在偏度为0但是不左右对称的分布,我们下面简单给出的一个例子,你可以尝试验证一下。

image.png-6.4kB

峰度(Kurtosis)

image.png-2.5kB

峰度用于衡量分布的尖峰或平扁的程度。

当峰度>3时,可以认为尖峰’很尖了‘。

  1. # 峰态(Kurtosis)
  2. xs = np.linspace(-6,6,300)
  3. normal = stats.norm.pdf(xs)
  4. # Plot some example distributions
  5. fig = plt.figure(figsize=(15, 5))
  6. plt.plot(xs, stats.laplace.pdf(xs), label='Leptokurtic')
  7. print ('Excess kurtosis of leptokurtic distribution:', (stats.laplace.stats(moments='k')))
  8. plt.plot(xs, normal, label='Mesokurtic (normal)')
  9. print ('Excess kurtosis of mesokurtic distribution:', (stats.norm.stats(moments='k')))
  10. plt.plot(xs,stats.cosine.pdf(xs), label='Platykurtic')
  11. print ('Excess kurtosis of platykurtic distribution:', (stats.cosine.stats(moments='k')))
  12. plt.legend()
  13. plt.show()
Excess kurtosis of leptokurtic distribution: 3.0
Excess kurtosis of mesokurtic distribution: 0.0
Excess kurtosis of platykurtic distribution: -0.5937628755982794

output_9_1.png-30.9kB

  1. #计算600036的偏峰与峰态
  2. import tushare as ts
  3. data = ts.get_k_data('600036', start='2016-01-01', end='2016-12-31', ktype='D',autype='qfq')
  4. data.index = pd.to_datetime(data['date'],format='%Y-%m-%d')
  5. data['returns'] = data['close'].pct_change()[1:]
  6. returns = data['returns'].dropna()
  7. print ('Skew:', stats.skew(returns))
  8. print ('kurtosis:', stats.kurtosis(returns))
  9. fig = plt.figure(figsize=(15, 5))
  10. plt.hist(returns, 30)
  11. plt.show()
Skew: -0.08398804531191496
kurtosis: 2.8607833058726095

output_10_1.png-5.2kB

3.SciPy

Scipy是世界上著名的Python开源科学计算库,建立在Numpy之上。它增加的功能包括数值积分、最优化、统计和一些专用函数。提供很多常用而且强大的功能,方便好用。

用scipy分析样本

  1. import numpy as np
  2. import random
  3. import scipy.stats as stats
  4. random.seed(7)
  5. # 生成符合正态分析的随机数
  6. generated = np.random.normal(loc=0,scale=1,size=1000)
  7. # 可以使用fit()方法对随机取样序列x进行拟合,返回的是与随机取样值最吻合的随机变量的参数
  8. Mean,std = stats.norm.fit(generated)
  9. print('Mean =',Mean,',std =',std)
  10. # 得到数据所在区域中某一百分比处的数值
  11. l = stats.scoreatpercentile(generated,95)
  12. print('95% point: ',l)
  13. # 反过来,得到数值所在的百分比
  14. print(u'%s location:'%l,stats.percentileofscore(generated,l))
Mean = 0.000664258193341 ,std = 1.00992857822
95% point:  1.75098752215
1.75098752215 location: 95.0

用scipy比较两个样本

  1. sample1 = np.random.normal(loc=0,scale=1,size=1000)
  2. sample2 = np.random.normal(loc=2,scale=2,size=1000)

使用ttest_ind可以检验两组不同的样本是否有相同的均值.返回的p-value表示两组样本均值相同的概率。

  1. a = stats.ttest_ind(sample1,sample2)
  2. print('pValue of Ttest_ind is %s'%a.pvalue)
pValue of Ttest_ind is 1.42142772403e-155

使用Kolmogorov-Smirnov检验判断两组样本是否来自同一个分布,返回的p-value表示两组样本来自同一分布的概率

  1. a = stats.ks_2samp(sample1,sample2)
  2. print('pValue of Kolmogorov-Smirnov Test :%s'%a.pvalue)
pValue of Kolmogorov-Smirnov Test :3.47313005428e-136

使用detrend方法去除趋势。

  1. from scipy import signal
  2. r_add1 = returns+1
  3. cumulative_r = r_add1.cumprod() # 快速获得累积收益
  4. detrend_returns=signal.detrend(cumulative_r)
  5. plt.figure(figsize=(10,8))
  6. plt.subplot(211)
  7. plt.plot(cumulative_r)
  8. plt.subplot(212)
  9. plt.plot(detrend_returns)
  10. plt.show()

output_21_0.png-40.6kB

4. Scipy.stats.probplot

probplot可以用来帮助我们确定样本数据的分布特性。

prob-plot和横坐标表示目标分布的分位数,纵坐标表示样本分布对应的分位数。

目标分布以参数的方式传入(dist),默认是norm正态分布。

如果看到一条45度角的直线,则说明样本分布和目标分布一致。

  1. import pylab
  2. stats.probplot(generated, dist="norm",plot=pylab)
  3. pylab.show()

output_23_0.png-10.8kB

5. 不同probplot图表反映的特性

使用probplot可以直观的比较样本分布和正态分布的差异,判断样本分布峰度,偏度等特性。

  1. import matplotlib.pyplot as plt
  2. nsample = 1000
  3. plt.figure(figsize=(10,8))
  4. ax1 = plt.subplot(321)
  5. x1 = stats.t.rvs(5, size=nsample) # 自由度低的t-分布, 厚尾
  6. res = stats.probplot(x1, plot=plt)
  7. ax2 = plt.subplot(322) # 自由度高的t-分布, 和正态分布很相近
  8. x2 = stats.t.rvs(30, size=nsample)
  9. res = stats.probplot(x2, plot=plt)
  10. ax3 = plt.subplot(323)
  11. x3 = stats.norm.rvs(loc=[0,5], scale=[1,1.5],size=(nsample//2,2)).ravel()
  12. # 两个正态分布的混合
  13. res = stats.probplot(x3, plot=plt)
  14. ax4 = plt.subplot(324)
  15. x4 = stats.norm.rvs(loc=0, scale=1, size=nsample) # 标准正态分布
  16. res = stats.probplot(x4, plot=plt)
  17. ax5 = plt.subplot(325)
  18. x5 = stats.f.rvs(4,10,loc=0, scale=1, size=nsample) # skewness < 0
  19. res = stats.probplot(x5, plot=plt)
  20. ax6 = plt.subplot(326)
  21. x6 = -stats.lognorm.rvs(s=0.7, loc=-10, scale=1, size=nsample) # skewness > 0
  22. res = stats.probplot(x6, plot=plt)

output_25_0.png-38.6kB

6. BoxPlot

同probplot一样,boxplot也可以用来区分样本分布的斜率峰度等属性。

  1. import pandas as pd
  2. boxData = pd.DataFrame({'1_t_5':x1,'2_t_30':x2,'3_mixNorm':x3,
  3. '4_normal':x4,'5_leftS':x5,'6_rightS':x6})
  4. print(boxData.head())
      1_t_5    2_t_30  3_mixNorm  4_normal   5_leftS  6_rightS
0 -1.379984  0.525020   1.508090 -2.074363  0.961589  8.629098
1 -2.668370 -0.455317   3.325578 -1.155878  0.765616  7.787245
2  0.905854  2.933671  -1.787563 -0.840319  0.039525  8.456012
3 -1.868835  1.640838   7.686157 -0.557648  0.712965  9.483665
4  0.067156  0.273633   0.233261  0.027595  0.577027  3.814535
  1. boxData.boxplot()
<matplotlib.axes._subplots.AxesSubplot at 0x1b263a6f8d0>

output_28_1.png-9.1kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注