1. 程式人生 > >資料特徵分析技能—— 相關性檢驗

資料特徵分析技能—— 相關性檢驗

資料特徵分析技能—— 相關性檢驗

相關性分析是指對兩個或多個具備相關性的變數元素進行分析,從而衡量兩個變數因素的相關密切程度
一般常用四種方法:
- 畫圖判斷
- pearson(皮爾遜)相關係數
- sperman(斯皮爾曼)相關係數
- Cosine similarity (餘弦相關係數)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
% matplotlib inline

繪製圖形判斷

一般對於強相關性的兩個變數,畫圖就能定性判斷是否相關

data1 = pd.Series(np.random.rand(50)*100).sort_values()
data2 = pd.Series(np.random.rand(50)*50).sort_values()
data3 = pd.Series(np.random.rand(50)*500).sort_values(ascending = False)
# 建立三個資料:data1為0-100的隨機數並從小到大排列,data2為0-50的隨機數並從小到大排列,data3為0-500的隨機數並從大到小排列,

fig = plt.figure(figsize = (10,4))
ax1 = fig.add_subplot(1
,2,1) ax1.scatter(data1, data2) plt.grid() # 正線性相關 ax2 = fig.add_subplot(1,2,2) ax2.scatter(data1, data3) plt.grid() # 負線性相關

這裡寫圖片描述

# (2)散點圖矩陣初判多變數間關係

data = pd.DataFrame(np.random.randn(200,4)*100, columns = ['A','B','C','D'])
pd.plotting.scatter_matrix(data,figsize=(8,8),
                         c = 'k'
, marker = '+', diagonal='hist', alpha = 0.8, range_padding=0.1) data.head()
A B C D
0 83.463300 108.208281 -16.441879 -69.039664
1 -114.341786 -176.341932 -64.282506 54.378911
2 -108.781464 116.223511 11.996554 4.445215
3 -124.358401 -74.357458 -46.089528 -73.539092
4 87.330398 205.767923 59.964420 137.955811

這裡寫圖片描述

pearson(皮爾遜)相關係數

要求樣本滿足正態分佈
- 兩個變數之間的皮爾遜相關係數定義為兩個變數之間的協方差和標準差的商,其值介於-1與1之間

  • 公式:

    協方差:
    

    s x y = 1 n 1 k = 1 n ( x k x ¯ ) ( y k y ¯ )

    標準差:
    

    s x = 1 n 1 k = 1 n ( x k x ¯ ) 2

    皮爾遜相關係數: 
    

    s x y s x s y = k = 1 n ( x k x ¯ ) ( y k y ¯ ) k = 1 n ( x k x ¯ ) 2 k = 1 n ( y k y ¯ ) 2

data1 = pd.Series(np.random.rand(100)*100).sort_values()
data2 = pd.Series(np.random.rand(100)*50).sort_values()
data = pd.DataFrame({'value1':data1.values,
                     'value2':data2.values})
print(data.head())
print('------')
# 建立樣本資料

u1,u2 = data['value1'].mean(),data['value2'].mean()  # 計算均值
std1,std2 = data['value1'].std(),data['value2'].std()  # 計算標準差
print('value1正態性檢驗:\n',stats.kstest(data['value1'], 'norm', (u1, std1)))
print('value2正態性檢驗:\n',stats.kstest(data['value2'], 'norm', (u2, std2)))
print('------')
# 正態性檢驗 → pvalue >0.05


data['(x-u1)*(y-u2)'] = (data['value1'] - u1) * (data['value2'] - u2)
data['(x-u1)**2'] = (data['value1'] - u1)**2
data['(y-u2)**2'] = (data['value2'] - u2)**2
print(data.head())
print('------')
# 製作Pearson相關係數求值表

r = data['(x-u1)*(y-u2)'].sum() / (np.sqrt(data['(x-u1)**2'].sum() * data['(y-u2)**2'].sum()))
print('Pearson相關係數為:%.4f' % r)
# 求出r
# |r| > 0.8 → 高度線性相關
     value1    value2
0  0.438432  0.486913
1  2.974424  0.663775
2  4.497743  1.417196
3  5.490366  2.047252
4  6.216346  3.455314

------
value1正態性檢驗:
 KstestResult(statistic=0.07534983222255448, pvalue=0.6116837468934935)
value2正態性檢驗:
 KstestResult(statistic=0.11048646902786918, pvalue=0.1614817955196972)
------

     value1    value2  (x-u1)*(y-u2)    (x-u1)**2   (y-u2)**2
0  0.438432  0.486913    1201.352006  2597.621877  555.603052
1  2.974424  0.663775    1133.009967  2345.549928  547.296636
2  4.497743  1.417196    1062.031735  2200.319086  512.612654
3  5.490366  2.047252    1010.628854  2108.181383  484.479509
4  6.216346  3.455314     931.020494  2042.041746  424.476709
------
Pearson相關係數為:0.9937
# Pearson相關係數 - 演算法

data1 = pd.Series(np.random.rand(100)*100).sort_values()
data2 = pd.Series(np.random.rand(100)*50).sort_values()
data = pd.DataFrame({'value1':data1.values,
                     'value2':data2.values})
print(data.head())
print('------')
# 建立樣本資料

data.corr()
# pandas相關性方法:data.corr(method='pearson', min_periods=1) → 直接給出資料欄位的相關係數矩陣
# method預設pearson
value1 value2 0 0.983096 0.368653 1 1.107613 0.509117 2 1.130588 0.755587 3 2.996367 0.909899 4 3.283088 1.233879 ——
value1 value2
value1 1.000000 0.996077
value2 0.996077 1.000000

Sperman秩相關係數

皮爾森相關係數主要用於服從正太分佈的連續變數,對於不服從正太分佈的變數,分類關聯性可採用Sperman秩相關係數,也稱 等級相關係數

計算方法:
- 對兩個變數按照取值大小從小到大編秩,Rx代表Xi的秩次,Ry代表Yi的秩次
- 如果兩個變數秩次一樣,則秩次為(index1+index2)/ 2
- di = Rx -Ry
公式:
ρ s = 1 6 d i 2 n ( n 2 1 )

data = pd.DataFrame({'智商':[106,86,100,101,99,103,97,113,112,110],
                    '每週看電視小時數':[7,0,27,50,28,29,20,12,6,17]})
print(data)
print('------')
# 建立樣本資料

data.sort_values('智商', inplace=True)
data['range1'] = np.arange(1,len(data)+1)
data.sort_values('每週看電視小時數', inplace=True)
data['range2'] = np.arange(1,len(data)+1)
print(data)
print('------')
# “智商”、“每週看電視小時數”重新按照從小到大排序,並設定秩次index

data['d'] = data['range1'] - data['range2']
data['d2'] = data['d']**2
print(data)
print('------')
# 求出di,di2

n = len(data)
rs = 1 - 6 * (data['d2'].sum()) / (n * (n**2 - 1))
print('Sperman秩相關係數為:%.4f' % rs)
# 求出rs
    智商  每週看電視小時數
0  106         7
1   86         0
2  100        27
3  101        50
4   99        28
5  103        29
6   97        20
7  113        12
8  112         6
9  110        17
------
    智商  每週看電視小時數  range1  range2
1   86         0       1       1
8  112         6       9       2
0  106         7       7       3
7  113        12      10       4
9  110        17       8       5
6   97        20       2       6
2  100        27       4       7
4   99        28       3       8
5  103        29       6       9
3  101        50       5      10
------
    智商  每週看電視小時數  range1  range2  d  d2
1   86         0       1       1  0   0
8  112         6       9       2  7  49
0  106         7       7       3  4  16
7  113        12      10       4  6  36
9  110        17       8       5  3   9
6   97        20       2       6 -4  16
2  100        27       4       7 -3   9
4   99        28       3       8 -5  25
5  103        29       6       9 -3   9
3  101        50       5      10 -5  25
------
Sperman秩相關係數為:-0.1758
# spearman相關係數 - 演算法

data = pd.DataFrame({'智商':[106,86,100,101,99,103,97,113,112,110],
                    '每週看電視小時數':[7,0,27,50,28,29,20,12,6,17]})
print(data)
print('------')
# 建立樣本資料

data.corr(method='spearman')
# pandas相關性方法:data.corr(method='pearson', min_periods=1) → 直接給出資料欄位的相關係數矩陣
# method預設pearson
智商 每週看電視小時數 0 106 7 1 86 0 2 100 27 3 101 50 4 99 28 5 103 29 6 97 20 7 113 12 8 112 6 9 110 17 ——
智商 每週看電視小時數
智商 1.000000 -0.175758
每週看電視小時數 -0.175758 1.000000