easy-algorithm-interview-an.../math/calculations/手动计算均值,方差,协方差,皮尔逊系数.md

3.5 KiB
Raw Blame History

1.均值,方差

假设有个数组一共n个元素那么均值方差的计算公式为
均值:
\bar x = \frac{1}{n} \sum_{i=1}^n x_i

方差(整体方差):
var = \frac{1}{n} \sum_{i=1}^n (x_i - \bar x) ^ 2

方差(样本方差):
S = \frac{1}{n-1} \sum_{i=1}^n (x_i - \bar x) ^ 2

其中整体方差除的是n样本方差除的是n-1。

2.协方差与皮尔逊系数

协方差Covariance用于衡量两个随机变量的联合变化程度。所以计算协方差的时候需要输入两个变量。而方差是协方差的一种特殊情况即变量与自身的协方差。

cov(X, Y) = \frac{\sum_{i=1}^n(x_i - \bar x)(y_i - \bar y )}{n-1}

如果分母上除以的是n-1那么计算的是样本的协方差。如果除以的是n计算的是整体协方差。

两个变量之间的皮尔逊相关系数为两个变量之间的协方差与标准差的商:
\rho_{x,y} = \frac{cov(X,Y)}{\sigma_x \sigma_y} = \frac{E[(X-\mu_x)(X-\mu_y)]}{\sigma_x \sigma_y}

样本的皮尔逊系数,经常用字母r表示:

{\displaystyle r={\frac {\sum_{i=1}^{n}(X_{i}-{\overline {X}})(Y_{i}-{\overline {Y}})}{{\sqrt {\sum_{i=1}^{n}(X_{i}-{\overline {X}})^{2}}}{\sqrt {\sum_{i=1}^{n}(Y_{i}-{\overline {Y}})^{2}}}}}}

皮尔逊系数r是一个衡量线性独立的无量纲数其取值在[1, 1]之间。如果r=1表示完全线性相关。如果r=-1表示完全线性负相关。r=0即cov值为0说明两个变量不相关或者更准确地说叫作“线性无关”、“线性不相关”表明X 与Y 两随机变量之间没有线性相关性并非表示它们之间一定没有任何内在的非线性函数关系X、Y二者并不一定是统计独立。

3.代码实现

前面说了这么多理论,接下来我们看具体实现。

import numpy as np
import math
import pandas as pd

def t1():
    a = [5, 6, 16, 9]
    print(np.mean(a))
    print()

    # 整体方差除以n
    var = np.var(a)
    print(var)
    # 自己计算方差
    var2 = [math.pow(x-np.mean(a), 2) for x in a]
    print(np.mean(var2))
    print()

    # 样本方差除以n-1
    sample_var = np.var(a, ddof=1)
    print(sample_var)
    print()

    # 标准差
    std = np.std(a)
    std2 = np.std(a, ddof=1)
    print(std)
    print(std2)


t1()

输出结果:

9.0

18.5
18.5

24.666666666666668

4.301162633521313
4.96655480858378

下面再看看皮尔逊系数的计算

def t2():
    a = [i for i in range(10)]
    b = [2*x + 0.1 for x in a]

    dic = {"x": a, "y": b}
    df = pd.DataFrame(dic)
    print(df)
    print()
    print("dfcorr is: ", df.corr())

    # 手动计算pearson系数
    n = len(a)
    abar = sum(a)/float(len(a))
    bbar = sum(b)/float(len(b))
    covab = sum([(x-abar)*(y-bbar) for (x, y) in zip(a, b)]) / n

    stda = math.sqrt(sum([math.pow(x-abar, 2) for x in a]) / n)
    stdb = math.sqrt(sum([math.pow(y-bbar, 2) for y in b]) / n)

    print()
    print(covab)
    print(stda)
    print(stdb)
    print()
    corrnum = covab / (stda * stdb)
    print("corrnum is: ", corrnum)


t2()

输出结果

   x     y
0  0   0.1
1  1   2.1
2  2   4.1
3  3   6.1
4  4   8.1
5  5  10.1
6  6  12.1
7  7  14.1
8  8  16.1
9  9  18.1

dfcorr is:       x    y
x  1.0  1.0
y  1.0  1.0

16.5
2.8722813232690143
5.7445626465380295

corrnum is:  0.9999999999999998

x, y分别是两个变量 y = 2x + 0.1两者具有完全的线性相关性所以最后计算出来的pearson系数为1.0。