Python相关分析(python相关系数分析)
在我们的工作中,会有一个这样的场景,有若干数据罗列在我们的面前,这组数据相互之间可能会存在一些联系,可能是此增彼涨,或者是负相关,也可能是没有关联,那么我们就需要一种能把这种关联性定量的工具来对数据进行分析,从而给我们的决策提供支持,也就是我们在统计分析中经常提到的相关性分析。
基本概念:
(1)相关:反映两个随机变量关系强度的指标,在日常应用中,一般提到的相关均是指变量之间的线性相关。
(2)线性相关:最简单的一种关联,两个随机变量X/Y之间呈线性趋势关系,即两变量共同增大,或者一增一减
(3)曲线相关:两i变量之间存在一定的关系,但不呈线性关系,而是曲线
(4)非线性相关:X、Y两变量之间没有明显的线性关系,却存在一定的非线性关系,说明X仍是影响Y的因素。
(5)秩相关:也称等级相关,对原变量的分布不作要求,属于非参数统计方法。适用于那些不服从正态分布的资料,还有总体分布未知和原始数据用等级表示的资料。
(6)正相关与负相关:两变量X、Y 同时增大或减小,变化趋势是同向的,称为正相关,两变量一增一减,变化趋势是反向的,称为负相关
(7)完全相关:两变量之间线性相关的密切程度最高,相关系数的绝对值为1,分为完全正相关和完全负相关。
相关类型与判别方法
(1) 两个连续变量之间的相关
- Pearson相关:必须双变量符合正态分布。
- Spearman相关:双变量不符合正态分布或者一个不符合正态分布。对于服从Pearson相关系数的数据也可以计算Spearman相关系数,但统计效能比Pearson相关系数要低一些。
(2)两个分类变量之间的相关
- Spearman相关:只能在两个变量均为 有序分类 时使用
(3) 偏相关
- 在处理X 和Y 之间的相关性时,由于Z 与X 和Y 都有密切相关,因此Z 的存在会影响X 和Y 之间真实的相关性,故需要控制Z 后,研究X 和Y 之间的相关性。因此偏相关又叫作净相关。Z 可能为X 和Y 的共同因素或者中介因素。常见的偏相关是指Pearson偏相关,当然还有Spearman偏相关。
(4)典型相关
- 在处理的资料为两组变量之间的相关性时,就不能采用上面的相关性分析了,如一个班级学生的身体健康资料(身高、体重)与考试成绩(语文、数学、外语)之间的相关性,此时就是两组资料之间的相关性,应该采用典型相关分析。一般典型相关是指两组计量资料之间的相关,两组分类变量资料之间的典型相关叫作非线性典型相关。
(5)距离相关
- 距离相关用于计算数值变量之间的距离相关性,通常不单独分析,一般为聚类分析或者因子分析的中间过程。Distances过程就可以用于计算记录(或变量)间的距离(或相似程度),根据变量的不同类型,可以有许多距离、相似程度测量指标供用户选择。但由于本模块只是一个预分析的过程,因此距离分析并不会给出常用的p 值,而只给出各变量/记录之间的距离大小,以供用户自行判断相似性。
线性相关系数说明
前面说了这么多的相关分析类型,在我们实际工作中,应用较多的还是线性相关分析。本次介绍以线性分析分析为主
相关系数的大小关系到变量之间的有关系程度。
- 相关系数 r 是一个无单位的量值,且-1 < r < 1
- r >0 为正相关, r < 0 为负相关
- | r | 接近于1,说明相关性越好
那么我们如何判断大小呢?
- |r|<0.3 不存在线性关系
- 0.3<|r|<0.5 低度线性关系
- 0.5<|r|<0.8 显著线性关系
- |r|>0.8 高度线性关系
Python相关分析与示例
在本节相关分析中,主要引用 Scipy 包中相应函数进行分析。
(1)皮尔逊相关 Pearson
函数:scipy.stats.pearsonr(x, y)
- 皮尔逊相关系数和p值用于测试非相关性。p值的计算依赖于每个数据集均呈正态分布的假设
参数:
- x, y:输入数据,数组/列表
返回值:
- r:皮尔逊相关系数
- p:float,双侧p值
'''
示例:某地10名一年级女大学生的胸围(cm)与肺活量(L) ,分析两者之间有无线性相关关系。
'''
from scipy import stats
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 数据
data = np.array([[72.5, 2.51], [83.9, 3.11], [78.3, 2.91], [88.4, 3.28], [77.1, 2.83],
[81.7, 2.86], [78.3, 3.16], [74.8, 1.91], [73.7, 2.98], [79.4, 3.28]])
plt.scatter(data[:, 0], data[:, 1])
plt.show()
# 正态性检验
p1_value= stats.shapiro(data[:, 0])[1]
if p1_value < 0.05:
print('p_value: ', p1_value)
print('-- 不符合正态分布 --')
else:
print('p_value: ', p1_value)
print('-- 符合正态分布 --')
p2_value= stats.shapiro(data[:, 1])[1]
if p2_value < 0.05:
print('p_value: ', p2_value)
print('-- 不符合正态分布 --')
else:
print('\np_value: ', p2_value)
print('-- 符合正态分布 --')
(corr_index, p_value) = stats.pearsonr(data[:, 0], data[:, 1])
print('\n相关系数 = ', corr_index, '\n', '\n显著性差异p = ', p_value)
(2)肯德尔相关 Kendall
函数:
scipy.stats.kendalltau(x, y, nan_policy='propagate', method='auto')
- 计算Kendalltau,这是序数数据的相关度量。
参数:
- a, b:输入数据,一维或二维数组
- nan_policy: {propagate,raise,omit},可选;确定输入数据包括nan时如何处理;propagate: 返回nan;raise: 返回一个错误;omit: 执行计算时忽略 nan 值
- method:{auto, asymphotic, exact},可选;定义用于计算p值的方法。auto:根据速度和精度之间的权衡选择合适的方法; asymphotic:使用对大样本有效的正态近似;exact:计算确切的p值,但仅当不存在联系时才能使用
返回值:
- r:皮尔逊相关系数
- p:float,双侧p值
''' 肯德尔相关'''
'''
示例:某医院测量了72名胃癌患者基因异常书与临床分期等级情况,其中变量CP表示临床分期,
gn表示异常基因数目,分析临床分析与基因遗传数目之间存在相关性系。
'''
from scipy import stats
import pandas as pd
import numpy as np
import os
os.chdir('D:/Data_example')
df = pd.read_csv('ex9_1_kendll.csv', encoding = 'gbk')
print(df.head())
# 相关性检验
(corr_index, p_value) = stats.kendalltau(df['cp'], df['gn'])
print('相关系数 = ', corr_index, '\n', '\n显著性差异p = ', p_value)
(3)斯皮尔曼相关 Spearman
函数:
scipy.stats.spearmanr(a, b=None, axis=0, nan_policy='propagate')
- 计算具有相关p值的 Spearman相关系数,
- 与Pearson相关性不同,Spearman相关性不假定两个数据集都呈正态分布。但对于大于500左右的数据集可能是合理的。
参数:
- a, b:输入数据,一维或二维数组,b可为缺失
- axis:默认为0,则每一列代表一个变量;如果axis = 1,则转换关系:每行代表一个变量
- nan_policy: {propagate,raise,omit},可选;确定输入数据包括nan时如何处理;
propagate: 返回nan;
raise: 返回一个错误;
omit: 执行计算时忽略 nan 值
返回值:
- r:皮尔逊相关系数
- p:float,双侧p值
'''
示例:某医师收集并测定95例糖尿病患者的体重指数BMI、HOMAR指数、胰岛素与瘦素比值A/L等指标,
分析指标之间的相关性。
'''
from scipy import stats
import pandas as pd
import numpy as np
import os
from statsmodels.stats.diagnostic import lillifors
import matplotlib.pyplot as plt
os.chdir('D:/Data_example')
df = pd.read_csv('ex9_2_spearmanr.csv', encoding = 'utf-8')
print(df.head())
# 相关视图
import matplotlib.pyplot as plt
pd.scatter_matrix(df[['BMI', 'HOMAR', 'AL']], figsize = (10, 8))
plt.show()
# 正态性检验
p1_value= lillifors(df['BMI'])[1]
if p1_value < 0.05:
print('p_value: ', p1_value)
print('-- 不符合正态分布 --')
else:
print('p_value: ', p1_value)
print('-- 符合正态分布 --')
p2_value= lillifors(df['HOMAR'])[1]
if p2_value < 0.05:
print('p_value: ', p2_value)
print('-- 不符合正态分布 --')
else:
print('\np_value: ', p2_value)
print('-- 符合正态分布 --')
p3_value= lillifors(df['AL'])[1]
if p3_value < 0.05:
print('p_value: ', p3_value)
print('-- 不符合正态分布 --')
else:
print('\np_value: ', p3_value)
print('-- 符合正态分布 --')
# 相关分析
(corr_index, p_value) = stats.spearmanr(df['BMI'], df['HOMAR'])
print('\n BMI-HOMAR 相关系数 = ', corr_index, '\n', '\n显著性差异p = ', p_value)
# 相关分析
(corr_index, p_value) = stats.spearmanr(df['BMI'], df['AL'])
print('\n BMI-AL 相关系数 = ', corr_index, '\n', '\n显著性差异p = ', p_value)
# 相关分析
(corr_index, p_value) = stats.spearmanr(df['HOMAR'], df['AL'])
print('\n HOMAR-AL 相关系数 = ', corr_index, '\n', '\n显著性差异p = ', p_value)
(4)Pandas 相关分析
除 Scipy 包包含的相关分析函数,在pandas也有相应分析函数,如corr()。
函数:
DataFrame.corr(method='pearson', min_periods=1)
参数:
- method:可选值为{‘pearson’, ‘kendall’, ‘spearman’}
pearson:Pearson相关系数来衡量两个数据集合是否在一条线上面,即针对线性数据的相关系数计算,针对非线性数据便会有误差。
kendall:用于反映分类变量相关性的指标,即针对无序序列的相关系数,非正太分布的数据
spearman:非线性的,非正太分析的数据的相关系数
- min_periods:样本最少的数据量
返回值:
- 各类型之间的相关系数DataFrame表格
from scipy import stats
import pandas as pd
import numpy as np
import os
from statsmodels.stats.diagnostic import lillifors
os.chdir('D:/Data_example')
df = pd.read_csv('ex9_2_spearmanr.csv', encoding = 'utf-8')
# 相关分析
corr_index = df[['BMI', 'HOMAR', 'AL']].corr(method = 'spearman')
corr_index