之前在做金融数据项目的时候,有朋友问我有没有什么好的方法可以衡量股票收益。这个问题让我思考了很久。其实如果从本质上看股票的收益率,不就是数据吗?无非就是回报率。.我们常用的衡量数据的方法有均值、方差、偏度和峰度。均值和方差是我们看到和用的最多的方法,甚至在中学课本上都有提到,所以今天就来说说偏度和峰度这两个大家不常用的方法,结合python代码.偏度和峰度在数据分析中的简单应用。首先介绍一下偏度和峰度的概念。图1.偏度和峰度公式偏度(skewness),也称为偏度和偏度系数,是描述数据分布中偏度的方向和程度的量度。它是衡量数据分布不对称程度的数字特征。对于一个随机变量X,其偏度为样本的三阶标准化矩,计算公式如图1中公式(1)所示。偏度的度量是相对于正态分布,偏度正态分布为0。因此,我们说如果数据分布是对称的,则偏度为0;如果偏度>0,则可以认为分布是右偏的,也称为正偏态,即分布右侧有一条长尾巴;如果偏度<0,那么可以认为分布是左偏的,也叫负偏度,即分布的左边有一条长尾巴。正偏置和负偏置如图2所示。在图2中,左边的是正偏置,右边的是负偏置。图2.偏度和峰度(Kurtosis)示意图是描述数据分布的陡度或平滑度的统计量。通过计算峰度,我们可以确定数据分布比正态分布更陡峭还是更平坦。对于一个随机变量X,其峰度为样本的四阶标准中心矩,其计算公式如图1中的方程2所示。当峰度系数>0时,从形状上看更陡或比正态分布更厚;而峰度系数<0,从形状上看,它比正态分布更平坦或平坦尾部更细。在实际环境中,如果一个分区是肥尾的,则该分布往往比正态分布的尾部具有更高的“质量”,即它包含更多的极值。在我们常用的几种分布中,正态分布的峰度为0,均匀分布的峰度为-1.2,指数分布的峰度为6。峰度示意图如图3所示,其中第一个子图是峰度为0的情况,第二个子图是峰度大于0的情况,第三个是峰度小于0的情况。图3.峰度示意图说完基本概念,我们再来说说如何进行基于偏度和峰度的正态性检验。这里主要有两种方法,一种是Omnibus测试,一种是Jarque-Bera测试。图4Omnibus和JB检验的公式Omnibus检验的公式如图4中的公式(3)所示,其中Z1和Z2为两个归一化函数,g1和g2分别为偏度和峰度,在Z1的作用下而Z2,K的结果接近于卡方分布,我们可以用卡方分布来检验。这个公式的原理比较复杂。想了解的可以自行查找相关资料。Jarque-Bera检验的公式如图4中的公式(4)所示,其中n为样本量,该结果也接近于卡方分布,其原理在此不再赘述。两种检验均基于所用数据的正态分布,即做出如下假设。零假设H0:数据呈正态分布。备择假设H1:数据不是正态分布的。让我们用代码来说明偏度和峰度。先看数据,数据很简单,只有15行2列。数据描述了火灾事故的损失以及火灾现场与最近消防站之间的距离。前者的单位是千元,后者的单位是公里。数据如图5所示,其中distance是指火灾发生地点到最近消防站的距离,loss是指火灾事故造成的损失。图5.数据示例下面是代码,首先导入需要的库。importpandasapdimportmatplotlib.pyplotaspltimportstatsmodels.stats.apiassmsimportstatsmodels.formula.apiassmfffromstatsmodels.compatimportlzipfromstatsmodels.graphics.tsaplotsimportplot_acf下一步是读取数据并绘制图形。这些代码都很简单,我就不多解释了。file=r'C:\Users\data.xlsx'df=pd.read_excel(file)fig,ax=plt.subplots(figsize=(8,6))plt.ylabel('损失')plt.xlabel('distance')plt.plot(df['distance'],df['loss'],'bo-',label='loss')plt.legend()plt.show()结果如图6,从结果中我们可以看出这些点大致在一条直线上,所以我们使用线性回归来拟合这些数据。图6.数据连接图下面是生成模型和输出模型的结果。expr='loss~distance'results=smf.ols(expr,df).fit()#生成回归模型print(results.summary())结果如图7所示,从图中我们可以看出值Prob(F-statistic)的of为1.25e-08,很小,说明我们的一元线性回归模型是正确的,即loss和距离之间的线性关系是显着的。在图中,我们还可以看到Skew=-0.003,说明这部分数据非常接近正态分布,而Kurtosis=1.706,说明我们的数据比正态分布陡峭,是一个峰。另外从图中可以看出Omnibus=2.551,Prob(Omnibus)=0.279,Jarque-Bera(JB)=1.047,Prob(JB)=0.592,我们很难直接从数值中得出Omnibus和Jarque-Bera判断是否支持前面的备择假设,但是我们可以从Prob(Omnibus)和Prob(JB)这两个值来判断,因为这两个值比较大,那么我们不能拒绝之前的原假设,即H0是正确的,说明我们的数据服从正态分布。图7.模型结果描述接下来,我们将验证Skew、Kurtosis、Omnibus和Jarque-Bera(JB)的值,使用statsmodels自带的方法。代码如下所示。omn??ibus_label=['OmnibusK-squaredtest','Chi-squared(2)p-value']omnibus_test=sms.omni_normtest(results.resid)#omnibustestomnibus_results=lzip(omnibus_label,omnibus_test)jb_label=['Jarque-Beratest','卡方(2)p值','偏度','峰度']jb_test=sms.jarque_bera(results.resid)#jarque_bera测试jb_results=lzip(jb_label,jb_test)print(omnibus_results)print(jb_results)这里omnibus_label和jb_label是两个列表,里面包含了我们要测试的item名称,sms.omni_normtest是statsmodels自带的omnibus测试方法,sms.jarque_bera是statsmodels自带的jarque_bera测试方法。results.resid是残值。一共有15个值。我们的数据本身只有15分。这里的每个残差值对应于之前的每个数据点。sms.omni_normtest和sms.jarque_bera通过residual差异检查。lzip方法比较少见,用法类似于python中的原生函数zip。笔者这里是想让大家了解statsmodels,所以用了lzip。这里也可以直接使用zip。至于lzip和zip的区别,留给大家自己去学习吧。上面的结果如图8所示,从图8可以看出,我们得到的结果和上面的图7完全一样。这里我们使用sms.omni_normtest和sms.jarque_bera来验证,主要是对上图7结果的解释,帮助大家更好的学习statsmodels。图8.omnibus和jb测试的结果。本文主要使用statsmodels来讲解偏度和峰度在数据分析中的一些基本应用。想深入了解偏度、峰度、statsmodels的读者可以自行查阅相关资料。.
