正文
13 相关分析
协方差
| 两个随机变量之间关系 | 正相关 | 不相关(相互独立) | 负相关 |
|---|---|---|---|
| 协方差 | >0 | =0 | <0 |
X 与与自己的协方差就是 X 的方差
对于样本数据:
协方差可以反映两个变量的关联程度, 但是不好度量
13.2 皮尔森相关系数
皮尔森相关系数是用来度量两个连续型的随机正态变量之间的线性关系的一种随机变量特征量
协方差÷标准差
13.3 相关系数的计算与假设检验
13.3.1 相关系数的计算
1 矩阵中行数据之间的相关系数的计算和列数据之间的相关系数的计算
import numpy as np
tang = np.array([[10, 10, 8, 9, 7],
[4, 5, 4, 3, 3],
[3, 2, 1, 1, 1]])
print("data source")
print(tang)
print("corrcoef between rowdata") # 行数据相关关系矩阵
print(np.corrcoef(tang))
print("corrcoef between columndata") # 列数据相关关系矩阵
print(np.corrcoef(tang, rowvar=0))data source
[[10 10 8 9 7]
[ 4 5 4 3 3]
[ 3 2 1 1 1]]
corrcoef between rowdata
[[1. 0.64168895 0.77174363]
[0.64168895 1. 0.53452248]
[0.77174363 0.53452248 1. ]]
corrcoef between columndata
[[1. 0.9694552 0.9526832 0.9939441 0.97986371]
[0.9694552 1. 0.99813671 0.99053606 0.99890611]
[0.9526832 0.99813671 1. 0.98031562 0.99419163]
[0.9939441 0.99053606 0.98031562 1. 0.99587059]
[0.97986371 0.99890611 0.99419163 0.99587059 1. ]]
如 corrcoef between rowdata[0][1]或 corrcoef between rowdata[1][0]所表示的是数组第 0 行数据[10, 10, 8, 9, 7]和第一行数据[4, 5, 4, 3, 3]的相关系数 0.64168895
一组数据和自身的相关系数为 1
2 理论计算与函数计算之间的比较
import pandas as pd
import numpy as np
df = pd.DataFrame([[3.8, 4, 5.8, 8, 11.3, 14.4,16.5,16.2,13.8,10.8,6.7,4.7],
[77.7, 51.2, 60.1, 54.1, 55.4, 56.8, 45, 55.3, 67.5, 73.3, 76.6, 79.6]],
columns=range(1, 13),
index=["月平均气温 t/°C", "降雨量 p/mm"])
df.columns.name = "月份"
df| 月份 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 月平均气温 t/°C | 3.8 | 4.0 | 5.8 | 8.0 | 11.3 | 14.4 | 16.5 | 16.2 | 13.8 | 10.8 | 6.7 | 4.7 |
| 降雨量 p/mm | 77.7 | 51.2 | 60.1 | 54.1 | 55.4 | 56.8 | 45.0 | 55.3 | 67.5 | 73.3 | 76.6 | 79.6 |
伦敦市平均气温 t 与降水量 p 之间的相关系数:
np.corrcoef(df)array([[ 1. , -0.48949468],
[-0.48949468, 1. ]])
13.3.2 相关系数的显著性检验
10 个学生初一数学分数 X 与初二数学分数 Y 如下表所示, 求它们之间的相关系数, 并从总体角度判断初一和初二数学分数是否存在关联?
1 计算成绩间的相关系数
import pandas as pd
import numpy as np
tang = np.array([[74, 71, 72, 68, 76,73,67,70,65,74],
[76, 75, 71, 70, 76, 79, 65, 77, 62, 72]])
data = np.array([np.append(data[0], data[0].sum()), np.append(data[1], data[1].sum())])
c = list(range(1, 11))
c.append("总和")
df = pd.DataFrame(data, columns=c, index=["X", "Y"])
df.columns.name = "序号"
df| 序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 总和 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| X | 74 | 71 | 72 | 68 | 76 | 73 | 67 | 70 | 65 | 74 | 710 |
| Y | 76 | 75 | 71 | 70 | 76 | 79 | 65 | 77 | 62 | 72 | 723 |
np.corrcoef(tang)array([[1. , 0.7802972],
[0.7802972, 1. ]])
得到相关系数:
2 构建假设检验确定总体数据间是否存在关联
根据样本数据提出总体的一个假设
假设
对于成对数据的检验, 一般用 t 检验, 构建检验统计量
The Pearson linear correlation coefficient (r) for n pairs of independent observations can be tested against the null hypothesis (ie.: >no correlation) using the statistic
t = r*sqrt[ (n-2)/(1-r^2) ]
This statistic has a Student-t distribution with n-2 degrees of freedom.(此统计量具有具有 n-2 个自由度的学生 t 分布)
在显著水平的情况下, 采用双边检验, 可以得到相关系数, 即在显著水平 0.01 下, 初一数学成绩和初二成绩之间存在显著的相关关系
from scipy.stats import t
r = np.corrcoef(tang)[0][1]
t_value = r * np.sqrt(10 - 2) / np.sqrt(1 - r ** 2)
print("相关系数: ", t_value, '>', t.ppf(1 - 0.005, 8))
print("显著性水平: ", 2 * (1 - t.cdf(t_value, 8)), '<', "0.01")相关系数: 3.52891333162547 > 3.3553873313333957
显著性水平: 0.007744294734007395 < 0.01
import scipy.stats as stats
cor, pv = stats.pearsonr(tang[0], tang[1])
print("cor =", cor)
print("pv =", pv)cor = 0.7802972005173809
pv = 0.007744294734007256
cor 即为两组数据之间的相关系数 pv 为显著性水平
例 13.4
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
# https://docs.scipy.org/doc/scipy-0.19.1/reference/stats.html#module-scipy.stats
# data source
x = [10.35, 6.24, 3.18, 8.46, 3.21, 7.65, 4.32, 8.66, 9.12, 10.31]
y = [5.1, 3.15, 1.67, 4.33, 1.76, 4.11, 2.11, 4.88, 4.99, 5.12]
# compute correlation and pvalue
correlation,pvalue = stats.pearsonr(x,y)
print ('correlation',correlation)
print ('pvalue',pvalue)
# create figure and configuring
plt.figure(figsize=(8,5), dpi=80)
plt.subplot(111)
# plotting the scatter figure
plt.scatter(x,y,color='red')
# 绘制回归直线
x = np.linspace(2, 11, 2)
y = 0.5115 * x + 0.0649 # 这个值是计算器算的..
plt.plot(x, y, color="blue", alpha=0.2)
plt.show();correlation 0.9891763198690562
pvalue 5.926875946481136e-08
13.4 斯皮尔曼等级相关
13.4.1 皮尔森相关系数的局限性
对于非线性关系, 相关性的检测功效会下降
13.4.2 斯皮尔曼等级相关系数
【数据科学】斯皮尔曼的等级相关系数(Spearman's coefficient)
1 斯皮尔曼等级相关系数的表示
斯皮尔曼等级相关主要用于解决名称数据和顺序数据相关的问题.当两个变量值以等级次序排列或以等级次序表示时, 两个相应的总体并不一定呈正态分布, 样本容量也不一定大于 30, 这种情况下可以用斯皮尔曼等级相关来描述两个变量之间的相关关系.
为等级个数, 为二列成对变量的等级差数
-
无论两个变量的数据如何变化, 符合什么样的分布, 我们只关心每个数值在变量内的排列顺序(秩)
-
当每个变量是另一个的完美单调函数时,发生+1 或-1 的完美斯皮尔曼相关
-
数据中出现了有相同等级的数据,一般对于有相同等级的数据的个体用所占有的平均等级作为它们的共同等级,比如有两个数据大小相同,分别占据 5,6 等级,则将 5.5 作为它们的共同等级
3 斯皮尔曼等级相关系数显著性检验
4 应用 Python 函数库计算斯皮尔曼等级相关系数
1 直接计算斯皮尔曼等级相关系数
import numpy as np
import scipy.stats as stats
x = [10.35, 6.24, 3.18, 8.46, 3.21, 7.65, 4.32, 8.66, 9.12, 10.31]
y = [5.1, 3.15, 1.67, 4.33, 1.76, 4.11, 2.11, 4.88, 4.99, 5.12] correlation, pvalue = stats.spearmanr(x, y)
print('correlation:', correlation)
print('pvalue:', pvalue)correlation: 0.9878787878787878
pvalue: 9.307459988955517e-08
2 先将原始数据转换成等级数据, 再计算斯皮尔曼等级相关系数
import numpy as np
import scipy.stats as stats
x = [10.35, 6.24, 3.18, 8.46, 3.21, 7.65, 4.32, 8.66, 9.12, 10.31]
y = [5.1, 3.15, 1.67, 4.33, 1.76, 4.11, 2.11, 4.88, 4.99, 5.12]
# rankdata () 函数将数组作为输入参数,对数组内的每个元素进行排序,并以另一个相同长度的数组的形式返回结果。
x = stats.rankdata(x)
y = stats.rankdata(y)
print(x)
print(y)
correlation, pvalue = stats.spearmanr(x, y)
print('correlation:', correlation)
print('pvalue:', pvalue)[10. 4. 1. 6. 2. 5. 3. 7. 8. 9.]
[ 9. 4. 1. 6. 2. 5. 3. 7. 8. 10.]
correlation: 0.9878787878787878
pvalue: 9.307459988955517e-08
用等级数据计算得到的斯皮尔曼相关系数和显著性水平与原始数据计算得到的数据相同
from scipy.stats import t
import numpy as np
import scipy.stats as stats
x = [10.35, 6.24, 3.18, 8.46, 3.21, 7.65, 4.32, 8.66, 9.12, 10.31]
y = [5.1, 3.15, 1.67, 4.33, 1.76, 4.11, 2.11, 4.88, 4.99, 5.12]
x = stats.rankdata(x)
y = stats.rankdata(y)
correlation = 1 - (6 * ((x - y) ** 2).sum()) / (n ** 3 - n)
n = len(x)
r_s = 1 - (6 * ((x - y) ** 2).sum()) / (n ** 3 - n)
t_value = r_s * np.sqrt(n - 2) / (1 - r_s ** 2)
pvalue = 2 * (1 - t.cdf(t_value, n - 2))
print('correlation:', correlation)
print('pvalue:', pvalue)correlation: 0.9878787878787879
pvalue: 3.419486915845482e-14
13.5 肯德尔系数
描述 K 个评分这对 N 个对象评价的一致性
13.5.3 肯德尔相关系数的显著性检验
import scipy.stats as stats
x1 = [10, 9, 8, 7, 6]
x2 = [10, 8, 9, 6, 7]
tau, p_value = stats.kendalltau(x1, x2)
print("tau", tau)
print("p_value", p_value)tau 0.6
p_value 0.23333333333333334
说明等级数据 x1 和 x2 的肯德尔相关系数为 0.6, 其显著性水平约为 0.233, 二者呈现出较弱的一致性
13.6 质量相关分析
质量相关分析也是研究两个变量之间的相关关系的分析方法, 其中
一个变量描述事物总体的性质或特点, 如男与女, 优与劣, 及格与不及格等(一般是离散的形式)
另一个变量以数量形式描述事物的具体性质, 如智商, 学科分数, 身高, 体重等
这两个变量之间的相关关系就是质量相关
13.6.1 二列相关
1 二列相关的数学定义
当两个变量都是正态连续变量, 其中一个变量被人为地划分成二分变量
| 变量 | 含义 |
|---|---|
| 二分变量中某一类别频率的比率 | |
| 二分变量中另一类别频率的比率 | |
| 二分变量中类别相对应的连续变量的平均值 | |
| 二分变量中类别相对应的连续变量的平均值 | |
| 连续变量的标准差 | |
| 正态曲线中累积概率相对应的概率密度函数值 |
2 二列相关实例
例 13.10
某次考试中, 有 10 名考生的成绩如下表所示, 包含总分和一道问答题, 试求该道问答题的区分度(该问答题得分与卷面总分的相关度)(人为规定问答题6 为通过, 否则为未通过)
import pandas as pd
import numpy as np
from scipy.stats import norm
data = np.array([[75, 57, 73, 65, 67, 56, 63, 61, 65, 67],
[7, 6, 7, 4, 7, 4, 4, 4, 7, 6]])
df = pd.DataFrame(data, columns=range(1, 11), index=["卷面总分", "问答题总分"])
df.columns.name = "考生"
df| 考生 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 卷面总分 | 75 | 57 | 73 | 65 | 67 | 56 | 63 | 61 | 65 | 67 |
| 问答题总分 | 7 | 6 | 7 | 4 | 7 | 4 | 4 | 4 | 7 | 6 |
由于问答题以 6 分为界进行区分, 由样本数据确定
p = np.array(np.where(data[1] >= 6)).size / len(data[1])
q = np.array(np.where(data[1] < 6)).size / len(data[1])
print("p:", p)
print("q:", q)p: 0.6
q: 0.4
当时, 查正态分布表得到连续随机变量
x = norm.ppf(p)
print("x:", x)x: 0.2533471031357997
当时, 代入标准正态分布函数
得到
Y = norm.pdf(x)
print("Y:", Y)Y: 0.38634253349686054
根据问答题得分分类, 计算卷面总分相应类比的平均数及样本均方差
X_p_bar = data[0][np.where(data[1] >= 6)].mean()
X_q_bar = data[0][np.where(data[1] < 6)].mean()
sigma = data[0].std(ddof=1)
print("X_p_bar:", X_p_bar)
print("X_q_bar:", X_q_bar)
print("std:", sigma)X_p_bar: 67.33333333333333
X_q_bar: 61.25
std: 6.118278625016463
通过公式计算得到二列相关系数
R = (X_p_bar - X_q_bar) / sigma * p * q / Y
R0.617662281919257
从二列相关系数的值, 可以看到问答题得分对总分的区分度略高
13.6.2 点二列相关
质量分析中用来描述事物总体性质的离散变量, 如果其性质本身就具有离散性质, 而不是人为地将连续变量划分成为连续变量, 这时候的相关关系称为点二列相关.
13.6.3 Python 对点二列相关的支持
import scipy.stats as stats
x = [1,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,0,0,0]
y = [84,82,76,60,72,74,76,84,88,90,78,80,92,94,96,88,90,78,76,74]
coef,pvalue=stats.pointbiserialr(x, y)
print('pointbiserialcorrcoef',coef)
print('pvalue',pvalue)pointbiserialcorrcoef 0.7849870641173373
pvalue 4.145927973490357e-05
-
点二列相关系数约为 0.785, 说明两组数据具有较好的一致性
-
输出的显著性水平的值很小, 表示相关系数具有统计学意义
13.7 品质相关分析
如果两个变量都是用来描述事物的综合性质且都是划分成几种类别来表示, 则称这两个变量之间的相关关系为品质相关
有两种不同的品质相关: 列连相关和相关
13.7.1 列连相关系数
1 列连相关系数的数学表示
-
当至少一个变量被分成两个以上类别, 则这两个变量之间的相关程度可用列连相关系数来测度.
-
假设变量被分成个类别, 被分成个类别, 而且和至少有一个大于 2, 此时变量与变量的列连相关系数记为 C
-
记为观察数据属于变量的第个类别, 变量的第类别的频数
构造统计量:
其中, 这样可以得到列连相关系数的计算公式
对于列连相关, 可以用卡方检验进行总体性质推断, 若卡方检验显著, 则列连相关系数也显著
2 列连相关系数的计算实例
计算调查对象和态度之间的列连相关系数, 并进行显著性检验
| 调查对象/态度 | 赞成 | 不置可否 | 反对 | 总计 |
|---|---|---|---|---|
| 低年级学生 | 446 | 212 | 319 | 977 |
| 高年级学生 | 273 | 193 | 324 | 790 |
| 教师 | 262 | 325 | 177 | 764 |
| 总计 | 981 | 730 | 820 | 2531 |
import numpy as np
data = np.array([[446, 212, 319],
[273, 193, 324],
[262, 325, 177]])
N = data.sum()
Sum = 0
for a in range(data.shape[0]):
for b in range(data.shape[1]):
Sum += (data[a][b] ** 2) / (data[a].sum() * data.T[b].sum())
chi_square = N * (Sum - 1)
C = np.sqrt(chi_square / (N + chi_square))
print("chi_square:", chi_square)
print("C:", C)chi_square: 130.0172447754466
C: 0.22104293310887424
from scipy.stats import chi2
chi2.isf(0.01, 4)13.276704135987625
因为, 所以求得系数具有显著意义
13.7.2 相关
1 相关系数的数学定义
当两个变量都是二分变量, 则这两个变量之间的相关系数称为相关系数
| A 和 B 的 2x2 列连 | 合计 | ||
|---|---|---|---|
| A_1 | a | b | a+b |
| A_2 | c | d | c+d |
| 合计 | a+c | b+d | N=a+b+c+d |
则 A 和 B 的系数的计算公式可以表示为:
易证:
(正负号由的值决定)
2 相关系数的应用
| R/C | 肯定 | 否定 | 合计 |
|---|---|---|---|
| 男生 | 22 | 88 | 110 |
| 女生 | 18 | 42 | 60 |
| 合计 | 40 | 130 | 170 |
所以求得的相关系数不具有统计显著意义
13.8 偏相关与复相关
13.8.1 偏相关
在多要素所构成的系统中, 先不考虑其他要素的影响, 单独研究两个要素之间的相互关系的密切程度
1 一阶偏相关系数
控制 3, 计算 1 和 2 的净影响
3 组变量共有个一阶偏相关系数
2 二阶偏相关系数
4 组变量共有个二阶偏相关系数
13.8.2 复相关
-
反映几个要素与某一个要素之间的复相关程度, 复相关系数介于 0~1
-
复相关系数越大, 表明变量之间的相关程度越密切, 复相关系数为 1, 表示完全相关, 为 0, 表示不相关
-
复相关系数必≥单相关系数的绝对值
-
复相关系数必≥同一系列数据所求得的偏相关系数的绝对值, 即