numpy中的方差、協方差、相關係數

1、np.var

數學上學過方差:$$ D(X)=\sum_{i\in [0,n)} ({x-\bar{x}})^2 $$
np.var()其實是均方差,均方差的意義就是將方差進行了平均化,從而使得此值不會隨着數據的增多而發生變化。
np.std()是標準差,np.std()的平方等於np.var(),標準差在高斯分佈中用$\sigma$表示。
不管是方差仍是標準差,它們衡量的都是二階中心矩。爲何是二階而不是一階?這是一個問題。html

函數原型:numpy.var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=<class numpy._globals._NoValue>)
計算張量a在axis軸上的方差python

  • a:一個ndarray,不必定是一維
  • axis:可取值爲None,int,int元組。當取值爲None時,會把張量a展平成一維數組;當指定一個或多個int時,沿着axis指定的軸計算方差,其它軸的形狀會保留。
  • dtype:在計算方差的時候使用的數據類型,若是a是int類型的張量,計算方差時也會使用float32類型
  • out:放置計算結果的數組,主要用於節省空間,out的維度必須保證正確
  • ddof:int,ddof是「Delta Degrees of Freedom」,表示自由度的個數,在計算方差時,分子是各個值和均值的差的平方之和,分母爲(N-ddof)
  • keepdims:是否保留a的形狀

返回值variance是一個ndarray數組

import numpy as np

a = np.random.randint(0, 10, (2, 3))
print(a)
print(np.var(a))
print(np.var(a, axis=0))
print(np.var(a, axis=1))
print(np.var(a, keepdims=True))
print(np.var(a, axis=0, keepdims=True))
print(np.var(a, axis=(0, 1)))

輸出爲dom

[[2 1 5]
 [7 3 0]]
5.666666666666667
[6.25 1.   6.25]
[2.88888889 8.22222222]
[[5.66666667]]
[[6.25 1.   6.25]]
5.666666666666667

關於ddof函數

import numpy as np

a = np.random.randint(0, 10, 4)
print(np.var(a), '=',np.sum((a - np.mean(a)) ** 2) / len(a))
ddof = 1
print(np.var(a, ddof=ddof), '=',np.sum((a - np.mean(a)) ** 2) / (len(a) - ddof))

2、np.cov

np.cov用來計算協方差
函數原型:numpy.cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None, aweights=None)
首先理清兩個概念:code

  • variable:變量,也就是feature
  • observation:觀測,也就是樣本

參數介紹:htm

  • m是一個一維向量或者二維矩陣,當m爲一個向量時,它至關於一個1行n列的矩陣,最終輸出的協方差矩陣爲$1\times 1$的矩陣(也就是一個標量)。當m是一個二維矩陣時,它的每一行表示一個feature(numpy官方文檔稱之爲variable),每一列表示一個樣本(observation)。咱們想要知道的是feature之間的相關性。假設m是n行k列的二維矩陣,那麼輸出爲$n\times n$的協方差矩陣。
  • y和m同樣,能夠是一維向量,也能夠是二維矩陣。y至關於給m添加了若干個新行,也就是m=np.hstack(m,y)。y的列數必須和m一致,不然無法把m和y的行拼起來。實際上,這個參數是無關緊要的,由於單單用m矩陣就足夠了。舉例來講,m是一個n行k列的矩陣,y是一個p行k列的矩陣,那麼把m和y拼起來獲得一個(n+p)行k列的矩陣。在這個矩陣上計算協方差,獲得一個(n+p)階的方陣。
  • rowvar是一個布爾值,用來描述矩陣m和矩陣y的信息。默認狀況下,m矩陣的一行對應一個feature,一列對應一個樣本,每一個feature就被稱爲variable,rowvar的意思是每行表示一個feature。此值默認爲True。
  • bias,在計算協方差時,若是bias=True,分母爲N(N表示樣本數,也就是觀測個數),表示有偏估計;默認狀況下,此值爲False,分母爲N-1表示有偏估計。這個問題略微複雜。
  • ddof:表示自由度,當此值不爲None,分母爲N-ddof。當此值不爲None時,bias參數失效。
  • fweights:一個一維整型數組,表示每一個觀測出現的次數。提供此參數的目的是,防止m矩陣過大。
  • aweights:一個一維浮點數組,表示每一個觀測的權重。權重大代表這個觀測準確,權重小代表這個權重不過重要。

返回值:out一個方陣,它的維數等於feature的個數。blog

數學上的協方差的定義:
$$ cov(X,Y)= (X-\bar{X})\cdot (Y-\bar{Y}) $$
此式中,X和Y皆爲向量。方差是特殊的協方差D(X)=cov(X,X)。協方差表示的是兩個向量的關聯程度,其實就至關於:把兩個向量中的變量進行中心化(減去均值),而後計算剩餘向量的內積。
np.cov和數學上的協方差並不同,在無偏估計狀況下:$np.cov=\frac{cov}{n-1}$;在有偏估計狀況下,$np.cov=\frac{COV}{n}$。其中n表示X向量和Y向量的維度。
例子:方差是特殊地協方差文檔

a = [1, 2, 3, 4, 6] 
print(np.cov(a), np.var(a) * len(a) / (len(a) - 1))

例子:兩個變量的協方差get

import numpy as np
a, b = np.random.rand(2, 4)
print(np.cov(a, b))
print(np.cov([a, b]))
print(np.dot(a - np.mean(a), b - np.mean(b)) / (len(a) - 1))

例子:理解m和y的關係

import numpy as np

a = [[1, 2], [4, 7]]
b = [[7, 16], [17, 8]]
c = np.cov(a, b)
print(c)
print(np.vstack((a,b)))
print(np.cov(np.vstack((a, b))))

3、np.correlate

數學上相關係數的定義:$$ \ro(X,Y)=\frac{cov(X,Y)}{\sqrt{cov(X,X)\times cov(Y,Y)}}$$
函數原型:numpy.corrcoef(x, y=None, rowvar=True, bias=<class 'numpy._globals._NoValue'>, ddof=<class 'numpy._globals._NoValue'>)

理解了np.cov()函數以後,很容易理解np.correlate(),兩者參數幾乎如出一轍。
np.cov()描述的是兩個向量協同變化的程度,它的取值可能很是大,也可能很是小,這就致使無法直觀地衡量兩者協同變化的程度。相關係數其實是正則化的協方差,n個變量的相關係數造成一個n維方陣。

參數介紹:

  • x:一個一維向量或者二維矩陣,每行表示一個feature,每列表示一個樣本
  • y:列數和x一致,用來和x進行拼接,至關於添加了|y|個feature。
  • rowvar:布爾值,默認爲True,表示每行表示一個feature,也就是每行表示一個variable。
  • bias:已廢棄,不要使用它。
  • ddof:已廢棄,不要使用它。

返回值:R一個n維方陣,n的個數和變量的個數相同。

參考資料

PCA實現

相關文章
相關標籤/搜索