Python3学习(六十二):方差、标准差和协方差三者之间的定义与计算

2020-12-24 10:21:45 浏览数 (1)

参考链接: Python中的统计函数 2(方差度量)

转载自:博客园:寻自己 

https://www.cnblogs.com/xunziji/p/6772227.html?utm_source=itdadao&utm_medium=referral 

理解三者之间的区别与联系,要从定义入手,一步步来计算,同时也要互相比较理解,这样才够深刻。 

方差 

方差是各个数据与平均数之差的平方的平均数。在概率论和数理统计中,方差(英文Variance)用来度量随机变量和其数学期望(即均值)之间的偏离程度。在许多实际问题中,研究随机变量和均值之间的偏离程度有着很重要的意义。 

标准差 

方差开根号。 

协方差 

在概率论和统计学中,协方差用于衡量两个变量的总体误差。而方差是协方差的一种特殊情况,即当两个变量是相同的情况。 

可以通俗的理解为:两个变量在变化过程中是否同向变化?还是反方向变化?同向或反向程度如何? 

你变大,同时我也变大,说明两个变量是同向变化的,这是协方差就是正的。 

你变大,同时我变小,说明两个变量是反向变化的,这时协方差就是负的。 

如果我是自然人,而你是太阳,那么两者没有相关关系,这时协方差是0。 

从数值来看,协方差的数值越大,两个变量同向程度也就越大,反之亦然。 

可以看出来,协方差代表了两个变量之间的是否同时偏离均值,和偏离的方向是相同还是相反。 

公式:如果有X,Y两个变量,每个时刻的“X值与其均值之差”乘以“Y值与其均值之差”得到一个乘积,再对这每时刻的乘积求和并求出均值,即为协方差。 

方差,标准差与协方差之间的联系与区别: 

1. 方差和标准差都是对一组(一维)数据进行统计的,反映的是一维数组的离散程度;而协方差是对2组数据进行统计的,反映的是2组数据之间的相关性。 

2. 标准差和均值的量纲(单位)是一致的,在描述一个波动范围时标准差比方差更方便。比如一个班男生的平均身高是170cm,标准差是10cm,那么方差就是10cm^2。可以进行的比较简便的描述是本班男生身高分布是170±10cm,方差就无法做到这点。 

3. 方差可以看成是协方差的一种特殊情况,即2组数据完全相同。 

4. 协方差只表示线性相关的方向,取值正无穷到负无穷。 

利用实例来计算方差、标准差和协方差 

样本数据1:沪深300指数2017年3月份的涨跌额(%), [0.16,-0.67,-0.21,0.54,0.22,-0.15,-0.63,0.03,0.88,-0.04,0.20,0.52,-1.03,0.11,0.49,-0.47,0.35,0.80,-0.33,-0.24,-0.13,-0.82,0.56] 

1. 计算沪深300指数2017年3月份的涨跌额(%)的方差 

# Sample Date - SH000300 Earning in 2017-03

datas = [0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88, -0.04, 0.20, 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.80, -0.33, -0.24, -0.13, -0.82, 0.56]

mean1 = sum(datas)/len(datas) # result =  0.0060869565217391355

square_datas = []

for i in datas:

square_datas.append((i-mean1)*(i-mean1))

variance = sum(square_datas)/len(square_datas)

print(str(variance))

# result = 0.25349338374291114

# 当然如果你使用了numpy,那么求方差将会十分的简单:

import numpy as np

datas = [0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88, -0.04, 0.20, 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.80, -0.33, -0.24, -0.13, -0.82, 0.56]

variance = np.var(datas)

print(str(variance))

# result = 0.253493383743 

2. 计算沪深300指数2017年3月份的涨跌额(%)的标准差 

import math

# Sample Date - SH000300 Earning in 2017-03

datas = [0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88, -0.04, 0.20, 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.80, -0.33, -0.24, -0.13, -0.82, 0.56]

mean1 = sum(datas)/len(datas)

square_datas = []

for i in datas:

    square_datas.append((i-mean1)*(i-mean1))

variance = sum(square_datas)/len(square_datas)

standard_deviation = math.sqrt(variance)

print(str(standard_deviation))

# result = 0.5034812645401129

#当然如果你使用了numpy,那么求标准差将会十分的简单:

import numpy as np

# Sample Date - SH000300 Earning in 2017-03

datas = [0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88, -0.04, 0.20, 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.80, -0.33, -0.24, -0.13, -0.82, 0.56]

standard_deviation2 = np.std(datas, ddof = 0)

print(str(standard_deviation2))

# result =0.50348126454

请注意  ddof = 0 这个参数,这个是很重要的,只是稍后放在文末说明,因为虽然重要,但是却十分好理解。 

3.  计算沪深300指数2017年3月份的涨跌额(%)与 格力电器(SZ:000651) 2017年3月份的涨跌额(%)之间的协方差 

协方差是计算两组数据之间的关系,所以要引入第二个样本,即格力电器(SZ:000651) 2017年3月份的涨跌额(%) 

import math

# Sample Date - SH000300 Earning in 2017-03

datas_sh000300 = [0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88, -0.04, 0.20, 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.80, -0.33, -0.24, -0.13, -0.82, 0.56]

datas_sz000651 = [0.07, -0.55, -0.04, 3.11, 0.28, -0.50, 1.10, 1.97, -0.31, -0.55, 2.06, -0.24, -1.44, 1.56, 3.69, 0.53, 2.30, 1.09, -2.63, 0.29, 1.30, -1.54, 3.19]

mean_sh000300 = sum(datas_sh000300) / len(datas_sh000300)

mean_sz000651 = sum(datas_sz000651) / len(datas_sz000651)

temp_datas = []

for i in range(0, len(datas_sh000300)):

    temp_datas.append((datas_sh000300[i] - mean_sh000300) * (datas_sz000651[i] - mean_sz000651))

cov = sum(temp_datas)/len(temp_datas)

print(str(cov))

# result = 0.4385294896030246

当然如果你使用了numpy,那么求协方差将会十分的简单:

import numpy as np

# Sample Date - SH000300 Earning in 2017-03

datas_sh000300 = [0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88, -0.04, 0.20, 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.80, -0.33, -0.24, -0.13, -0.82, 0.56]

datas_sz000651 = [0.07, -0.55, -0.04, 3.11, 0.28, -0.50, 1.10, 1.97, -0.31, -0.55, 2.06, -0.24, -1.44, 1.56, 3.69, 0.53, 2.30, 1.09, -2.63, 0.29, 1.30, -1.54, 3.19]

cov2 = np.cov(datas_sh000300, datas_sz000651, ddof=0)[1][0]

print(str(cov2))

# result = 0.438529489603 

请注意  ddof = 0 这个参数,这个是很重要的,只是稍后放在文末说明,因为虽然重要,但是却十分好理解。 

从这个例子可以看出来,格力个股在2017年3月份是和沪深300指数正相关的,即指数涨,格力也大多是上涨的,只是 值偏小,两者之间偏离各自均值的幅度也不同,即,我们知道了2者正相关,但是不知道正相关的幅度是大是小,这个需要引入下一个名词,文章下面会介绍:相关系数。 

ddof = 0 参数的说明 

如果你从网上查找方差的公式,你会发现有2个公式! 

  和  

那么哪个是正确的呢?又有什么区别呢?这里就要说下贝赛尔修正: 

在上面的方差公式和标准差公式中,存在一个值为N的分母,其作用为将计算得到的累积偏差进行平均,从而消除数据集大小对计算数据离散程度所产生的影响。不过,使用N所计算得到的方差及标准差只能用来表示该数据集本身(population)的离散程度;如果数据集是某个更大的研究对象的样本(sample),那么在计算该研究对象的离散程度时,就需要对上述方差公式和标准差公式进行贝塞尔修正,将N替换为N-1: 

简单的说,是除以 N 还是 除以 N-1,则要看样本是否全,比如,我要统计全国20岁男性的平均身高,这时间你肯定拿不到全部20岁男性的身高,所以只能随机抽样 500名,这时间要除以 N-1,因为只是部分数据;但是我们算沪深300在2017年3月份的涨跌幅,我们是可以全部拿到3月份的数据的,所以我们拿到的是全部数据,这时间就要除以 N。 

相关系数 

在我们的例子中,求的沪深300在2017年3月份的方差为0.253493383743,标准差为0.5034812645401129。 

那么我们该如何理解呢? 

方差:如果 股票 B 的方差是 0.1,那么我们可以说 沪深300的离散度更大,因为沪深300 的方差>股票B的方差。 

标准差:沪深300的均值是:mean1 = sum(datas)/len(datas) = 0.0060869565217391355,即平均每天上涨 0.006%,那么我们描述,沪深300指数在2017年3月份平均日波动区间为[ 0.006%-0.50%,  0.006% 0.50% ] 

而协方差呢,如果我只有格力和沪深300的数据,我拿到的协方差值是0.438529489603,这个值只能表明是正相关的,但是正相关的程度呢,是沪深300上涨1%,格力也上涨1%,还是沪深300上涨1%,格力涨2%呢?我们从协方差的值中无从得知。 

这时间就需要另外一个变量来描述相关度的大小了:相关系数 

协方差的相关系数,不仅表示线性相关的方向,还表示线性相关的程度,取值[-1,1]。也就是说,相关系数为正值,说明一个变量变大另一个变量也变大;取负值说明一个变量变大另一个变量变小,取0说明两个变量没有相关关系。同时,相关系数的绝对值越接近1,线性关系越显著。 

计算公式为:就是用X、Y的协方差除以X的标准差乘以Y的标准差。 

用 Python Numpy 来实现代码如下: 

import numpy as np

import math

# Sample Date - SH000300 Earning in 2017-03

datas_sh000300 = [0.16, -0.67, -0.21, 0.54, 0.22, -0.15, -0.63, 0.03, 0.88, -0.04, 0.20, 0.52, -1.03, 0.11, 0.49, -0.47, 0.35, 0.80, -0.33, -0.24, -0.13, -0.82, 0.56]

datas_sz000651 = [0.07, -0.55, -0.04, 3.11, 0.28, -0.50, 1.10, 1.97, -0.31, -0.55, 2.06, -0.24, -1.44, 1.56, 3.69, 0.53, 2.30, 1.09, -2.63, 0.29, 1.30, -1.54, 3.19]

cov = np.cov(datas_sh000300, datas_sz000651, ddof=0)[1][0]

standard_deviation_sh000300 = np.std(datas_sh000300, ddof=0)

standard_deviation_sz000651 = np.std(datas_sz000651, ddof=0)

ppcc = cov/(standard_deviation_sh000300*standard_deviation_sz000651)

print(str(ppcc))

# result = 0.554372485367 

相关系数是  0.554372485367,可以看出来两者是正相关的,但是相关度很一般,至于一般的标准,就要看工作中的应用尺度了,如系数超过0.8,才存在配对交易的机会,否则,没有。

0 人点赞