当一个或几个变量取一定的值时,另一个变量有确定值与之具体严格相对应,则称这种关系为函数关系。
变量之间的影响不能够用具体的函数来度量,但变量之间的关系确实存在数量上不是严格对应的相互依存关系,称之为相关关系。
相关关系根据其分析方法和处理对象不同,可以分为简单相关分析、偏相关分析和非参数相关分析等。
相关分析根据相关关系表现形式不同,可以分为线性相关分析和非线性相关分析。
简单相关关系主要分析两个变量之间的相互依存的关系,可以通过主观观测和客观测度指标来衡量。
主观观测指标之间的相关关系,主要是通过两个变量之间散点图的手段进行。
客观测度主要是通过统计分析的方法,计算相关系数,利用相关关系数值的符号和大小来判定相关关系的方向和强弱。
import numpy as np
import pandas as pd
from scipy import stats
from sklearn.feature_selection import f_regression
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
# 导入数据
car_dict = {'brand_model':['Acura Legend V6','Audi 100','BMW 535i','Buick Century','Buick Riviera V6'],
'weight':[3265,2935,3640,2880,3465],
'circle':[42,39,39,41,41],
'max_speed':[163,141,209,151,231],
'horsepower': [160, 130, 208, 110, 165]}
car = pd.DataFrame(car_dict)
print(car)
# 画散点图矩阵
sns.pairplot(car)
plt.show()
结果为:
car数据集
brand_model weight circle max_speed horsepower
0 Acura Legend V6 3265 42 163 160
1 Audi 100 2935 39 141 130
2 BMW 535i 3640 39 209 208
3 Buick Century 2880 41 151 110
4 Buick Riviera V6 3465 41 231 165
相关系数( r r r,也称样本相关系数):描述线性相关程度和方向的统计量。
r = ∑ ( x − x ˉ ) ( y − y ˉ ) ∑ ( x − x ˉ ) 2 × ∑ ( y − y ˉ ) 2 r = \frac{\sum(x-\bar{x})(y-\bar{y})}{\sqrt{\sum(x-\bar{x})^2\times\sum(y-\bar{y})^2}} r=∑(x−xˉ)2×∑(y−yˉ)2∑(x−xˉ)(y−yˉ)
其中, r ∈ [ − 1 , 1 ] r\in[-1,1] r∈[−1,1]。
r r r的正负号表示相关关系的方向:
r = + 1 r = +1 r=+1,完全正线性相关
r = − 1 r = -1 r=−1,完全负线性相关
r < 0 r < 0 r<0,负线性相关
r > 0 r > 0 r>0,正线性相关
r = 0 r = 0 r=0,不存在线性关系
# numpy包计算样本相关系数
print(np.corrcoef((car['weight'],car['circle'],car['max_speed'],car['horsepower'])))
print(car.corr())
结果:
[[ 1. -0.0984517 0.87503571 0.96299045]
[-0.0984517 1. 0. -0.26035305]
[ 0.87503571 0. 1. 0.72725538]
[ 0.96299045 -0.26035305 0.72725538 1. ]]
print(car.corr())
结果:
weight circle max_speed horsepower
weight 1.000000 -0.098452 0.875036 0.962990
circle -0.098452 1.000000 0.000000 -0.260353
max_speed 0.875036 0.000000 1.000000 0.727255
horsepower 0.962990 -0.260353 0.727255 1.000000
计算两个指标间的相关系数
# cripy包计算样本相关系数
print(stats.pearsonr(car['weight'],car['max_speed'])) #(样本相关系数, P值)
结果:
(0.8750357068360751, 0.052023540358421314)
同时计算多个变量间的相关系数
corralation = []
for i in car[['weight','circle','horsepower']].columns:
corralation.append(stats.pearsonr(car['max_speed'],car[i]))
print(corralation)
结果:
[(0.8750357068360751, 0.052023540358421314),
(0.0, 1.0),
(0.727255378914049, 0.16381346667938196)]
# scikit-learn提供f_regrssion计算F统计量与P值,无法输出样本相关系数
F,P_Value = f_regression(car[['weight','circle','horsepower']],car['max_speed'])
print(F),print(P_Value)
结果:
[9.8034136 0. 3.36807994]
[0.05202354 1. 0.16381347]
简单相关关系有时不能真实反映现象之间的关系。由于相关系数的不可传递性,在进行相关分析时,往往要控制对 x x x、 y y y同时产生作用的变量 p p p的影响。剔除其他变量影响之后再进行相关分析的方法称之为偏相关分析(partial correlation analysis)。
r x y . p = r x y − r x p ∗ r x p ( 1 − r x p 2 ) ( 1 − r y p 2 ) r_{xy.p} = \frac{r_{xy}-r_{xp}*r_{xp}}{\sqrt{(1-r_{xp}^2)\sqrt{(1-r_{yp}^2)}}} rxy.p=(1−rxp2)(1−ryp2)rxy−rxp∗rxp
其中, r x y r_{xy} rxy、 r x p r_{xp} rxp、 r y p r_{yp} ryp分别表示 x x x和 y y y之间、 x x x和 p p p之间、 y y y和 p p p之间的简单相关系数。
python中没有计算偏相关系数的模块,自定义函数如下:
# 偏相关系数
# python中无模块可计算偏相关系数,自定义一个偏相关系数函数
def partial_corr(x, y, partial = []):
# x,y分别为考察相关关系的变量,partial为控制变量
xy, xyp = stats.pearsonr(x, y)
xp, xpp = stats.pearsonr(x, partial)
yp, ypp = stats.pearsonr(y, partial)
n = len(x)
df = n - 3
r = (xy - xp*yp)/(np.sqrt(1 - xp*xp)*np.sqrt(1 - yp*yp))
if abs(r) == 1.0:
prob = 0.0
else:
t = (r*np.sqrt(df))/np.sqrt(1 - r*r)
prob = (1 - stats.t.cdf(abs(t),df))**2
return r,prob
pcorrelation = []
for i in car[['weight','circle']].columns:
pcorrelation.append(partial_corr(car[i],car['max_speed'],partial = car['horsepower']))
print(pcorrelation)
结果:
[(0.9442998237624293, 0.0007756274082241067),
(0.285716213402416, 0.12755033194904572)]
点二列相关(point-biserial correlation)适用于两个变量中,一个是来自正态总体的定距或定比数据,另一变量是二分类数据。
一般将后者编码为0、1,然后计算 p e a r s o n pearson pearson相关系数:
r = x ‾ p − x ‾ q S x p q r = \frac {\overline{x}_p-\overline{x}_q}{S_x}\sqrt{pq} r=Sxxp−xqpq
其中, p p p表示二分类数据某类的占比, q = 1 − p q = 1 - p q=1−p表示另一类别的占比。 x ‾ p \overline{x}_p xp和 x ‾ q \overline{x}_q xq表示对应分类对应的另一个变量的平均数, S x S_x Sx为另一个变量的样本标准差。
数据及点二列相关系数计算:
# 点二列相关分析
score_by_gender = pd.DataFrame(
{'score':[68,81,78,91,91],
'gender':[1,1,0,0,1]})
print(stats.pointbiserialr(score_by_gender['gender'],score_by_gender['score']))
结果:
PointbiserialrResult(correlation=-0.25462635064312505,
pvalue=0.6793377775792051)
简单相关分析和偏相关分析广泛用于定量数据或连续型数据的研究。
对于定性数据的相关分析,往往从数据值的次序入手,并借助非参数统计分析的思想。次序在数列中代表了某个具体变量值的位置、等级或秩,因此这类相关系数通常称为非参数相关分析、等级相关分析、秩相关分析,其计算的相关系数为非参数相关系数、等级相关系数、秩相关系数。
Spearman相关系数主要测度顺序变量间的相关系数,在计算过程中只考虑变量值的顺序而不考虑变量值的大小。
其计算过程为:首先把变量值转换成在样本所有变量值中的排列次序,再利用 P e a r s o n Pearson Pearson方法求解转换后的两个变量对应的排列次序(rank,即“秩”或等级)的相关系数。
r = ∑ ( R x i − R ‾ x ) ( R y i − R ‾ y ) ∑ ( R x i − R ‾ x ) 2 ∑ ( R y i − R ‾ y ) 2 r = \frac{\sum(R_{x_{i}}-\overline{R}_x)(R_{y_{i}}-\overline{R}_y)}{\sqrt{\sum(R_{x_{i}}-\overline{R}_x)^2\sum(R_{y_{i}}-\overline{R}_y)^2}} r=∑(Rxi−Rx)2∑(Ryi−Ry)2∑(Rxi−Rx)(Ryi−Ry)
其中, R x i R_{x_{i}} Rxi和 R y i R_{y_{i}} Ryi分别表示第 i i i个 x x x变量和 y y y变量经过排序后的次序, R ‾ x \overline{R}_x Rx和 R ‾ y \overline{R}_y Ry分别表示 R x i R_{x_{i}} Rxi和 R y i R_{y_{i}} Ryi的均值。
# ===================================Spearman相关系数=============================
# Spearman相关系数
graduate = pd.DataFrame(
{'interest':[2,2,4,1,3],
'major':[2,2,3,1,3],
'teaching': [2, 1, 4, 2, 3],
'tutor': [2, 2, 4, 1, 3]})
# spearmanr,kendalltau函数计算对应的非参数相关系数
rho, p = stats.spearmanr(graduate)
print(rho)
print(p)
# ===================================Spearman相关系数=============================
结果:
[[1. 0.97332853 0.76315789 1. ]
[0.97332853 1. 0.7299964 0.97332853]
[0.76315789 0.7299964 1. 0.76315789]
[1. 0.97332853 0.76315789 1. ]]
[[0. 0.00520786 0.13333912 0. ]
[0.00520786 0. 0.16142315 0.00520786]
[0.13333912 0.16142315 0. 0.13333912]
[0. 0.00520786 0.13333912 0. ]]
kt = []
for i in graduate[['interest','major','teaching']]:
kt.append(stats.kendalltau(graduate[i],graduate['tutor']))
print(kt)
结果:
[KendalltauResult(correlation=1.0, pvalue=0.019176729141549054),
KendalltauResult(correlation=0.9428090415820632, pvalue=0.031686388539793796),
KendalltauResult(correlation=0.6666666666666666, pvalue=0.11843292891667201)]