Python資料相關性分析
概述
在我們的工作中,會有一個這樣的場景,有若干資料羅列在我們的面前,這組資料相互之間可能會存在一些聯絡,可能是此增彼漲,或者是負相關,也可能是沒有關聯,那麼我們就需要一種能把這種關聯性定量的工具來對資料進行分析,從而給我們的決策提供支援,本文即介紹如何使用 Python 進行資料相關性分析。
關鍵詞 python 方差 協方差 相關係數 離散度 pandas numpy
實驗資料準備
接下來,我們將使用 Anaconda 的 ipython 來演示如何使用 Python 資料相關性分析,我所使用的 Python 版本為 3.6.2 。
首先,我們將會建立兩個陣列,陣列內含有 20 個數據,均為 [0, 100] 區間內隨機生成。
a = [random.randint(0, 100) for a in range(20)]
b = [random.randint(0, 100) for a in range(20)]
print(a)
>> [35, 2, 75, 72, 55, 77, 69, 83, 3, 46, 31, 91, 72, 12, 15, 20, 39, 18, 57, 49]
print(b)
>> [25, 24, 72, 91, 27, 44, 85, 21, 0, 64, 44, 31, 6, 91, 1, 61, 5, 39, 24, 43]
期望
在進行相關性分析之前,我們需要先為最終的計算分析做好準備。我們在分析前,第一個準備的是計算資料的期望。對於期望的定義,離散變數和連續變數是不一樣的,具體定義如下:
- 對於連續隨機變數
在一般情況下,我們通過實驗或者調查統計獲取的資料很大一部分都屬於離散隨機變數,那麼這裡的期望我們也可以簡單的理解為平均數,那麼既然是平均數,那麼我們就可以非常簡單編寫一個計算離散變數的期望的函數了。
def mean(x):
return sum(x) / len(x)
mean(a)
>> 46.05
mean(b)
>> 39.9
離散度 - 方差與標準差
接下來,我們需要計算的是資料的離散程度,在統計上,我們通常會使用方差和標準差來描述。
方差和期望一樣,對於連續和離散的隨機變數有著不同的定義,具體定義如下:
- 對於連續隨機變數
與期望類似,這裡我們一般只考慮離散變數的方差。還有一點值得注意,我們上面的離散變數方差公式,最後是除以 n ,但實際上,我們計算樣本方差的時候一般會使用 n-1 ,具體原因可以參考知乎 《為什麼樣本方差(sample variance)的分母是 n-1?》。
而標準差,就是方差的平方根。那麼,我們也可以像上面計算期望一樣,給方差和標準差編寫函式。
# 計算每一項資料與均值的差
def de_mean(x):
x_bar = mean(x)
return [x_i - x_bar for x_i in x]
# 輔助計算函式 dot product 、sum_of_squares
def dot(v, w):
return sum(v_i * w_i for v_i, w_i in zip(v, w))
def sum_of_squares(v):
return dot(v, v)
# 方差
def variance(x):
n = len(x)
deviations = de_mean(x)
return sum_of_squares(deviations) / (n - 1)
# 標準差
import math
def standard_deviation(x):
return math.sqrt(variance(x))
variance(a)
>> 791.8394736842105
varance(b)
>> 850.5157894736841
協方差與相關係數
接下來,我們進入正題,我們開始計算兩組資料的相關性。我們一般採用相關係數來描述兩組資料的相關性,而相關係數則是由協方差除以兩個變數的標準差而得,相關係數的取值會在 [-1, 1] 之間,-1 表示完全負相關,1 表示完全相關。接下來,我們看一下協方差和相關係數的定義:
- 協方差
同樣的,我們根據上述的公式編寫函式。
# 協方差
def covariance(x, y):
n = len(x)
return dot(de_mean(x), de_mean(y)) / (n -1)
# 相關係數
def correlation(x, y):
stdev_x = standard_deviation(x)
stdev_y = standard_deviation(y)
if stdev_x > 0 and stdev_y > 0:
return covariance(x, y) / stdev_x / stdev_y
else:
return 0
covariance(a, b)
>> 150.95263157894735
correlation(a, b)
>> 0.18394200852440826
根據上面的結果,相關係數為 0.18,可以推斷這兩組隨機數有弱正相關。當然,我們知道,這兩組資料都是使用 random 函式隨機生成出來的,其實並沒有什麼相關性,這也是在資料處理中,需要特別留意的一個地方,統計的方法可以給我們一個定量的數值可供分析,但實際的分析也需要結合實際以及更多的情況綜合考慮。
使用 numpy 計算協方差矩陣 相關係數
一般我們日常工作,都不會像上面一樣把什麼期望、方差、協方差一類的函式都重新寫一遍,上面的程式碼只是讓我們對這些計算更加熟悉。我們通常情況下會使用 numpy 一類封裝好的函式,以下將演示一下如何使用 numpy 計算協方差。
import numpy as np
# 先構造一個矩陣
ab = np.array([a, b])
# 計算協方差矩陣
np.cov(ab)
>> array([[ 791.83947368, 150.95263158],
[ 150.95263158, 850.51578947]])
這裡我們可以看到,這裡使用 np.cov 函式,輸出的結果是一個矩陣,這就是協方差矩陣。協方差矩陣資料的看法也不難,我們可以以上面的結果為例,矩陣1行1列,表示的是 a 資料的方差,這和我們上面的計算結果一致,然後1行2列和2行1列分別是 a b 以及 b a 的協方差,所以他們的值是一樣的,然後最後2行2列就是 b 資料的方差。
接下來,我們繼續使用 numpy 計算相關係數
np.corrcoef(ab)
>> array([[ 1. , 0.18394201],
[ 0.18394201, 1. ]])
計算相關係數,我們使用 numpy 的 corrcoef 函式,這裡的輸出也是一個矩陣,這個矩陣資料的含義同上面的協方差類似,我們可以看到,這裡我們的相關係數是 0.18 ,和我們上面自己編寫的函式計算的結果一致。
使用 pandas 計算協方差、相關係數
除了使用 numpy,我們比較常用的 python 資料處理庫還有 pandas,很多金融資料分析的框架都會使用 pandas 庫,以下將演示如何使用 pandas 庫計算協方差和相關係數。
import pandas as pd
# 使用 DataFrame 作為資料結構,為方便計算,我們會將 ab 矩陣轉置
dfab = pd.DataFrame(ab.T, columns=['A', 'B'])
# A B 協方差
dfab.A.cov(dfab.B)
>> 150.95263157894738
# A B 相關係數
dfab.A.corr(dfab.B)
>> 0.18394200852440828
dfab
>> A B
0 35 25
1 2 24
2 75 72
3 72 91
4 55 27
5 77 44
6 69 85
7 83 21
8 3 0
9 46 64
10 31 44
11 91 31
12 72 6
13 12 91
14 15 1
15 20 61
16 39 5
17 18 39
18 57 24
19 49 43
可以看到,和 numpy 相比,pandas 對於有多組資料的協方差、相關係數的計算比 numpy 更為簡便、清晰,我們可以指定計算具體的兩組資料的協方差、相關係數,這樣就不需要再分析結果的協方差矩陣了。
小結
本文通過建立兩組隨機的陣列,然後通過參考定義公式編寫函式,再到使用 numpy 以及 pandas 進行協方差、相關係數的計算。到這裡我們應該已經瞭解了資料相關性分析的原理,以及簡單的具體實踐使用方法,日後在工作中遇到需要做資料相關性分析的時候,就可以派上用場了。