三种常用相关性系数总结:概念+代码实现

一、相关系数

前言

  • 相关系数取值范围:[0, 1]
  • 负值: 表示两个变量成负相关;
  • 正值: 表示两个变量成正相关;
  • 0: 表示两个变量无相关关系(一个变量的增大减小对另一个的取值没有影响)

1、斯皮尔曼相关系数

(1)基本概念

  • 皮尔逊相关是关于两个随机变量之间的线性关系强度的统计度量,而斯皮尔曼相关考察的是两者单调关系的强度,就是两者在变大或变小的趋势上多大程度上保持步调一致,哪怕没有保持比例关系;
  • 计算皮尔逊相关系数时使用的是数据样本值本身,而计算斯皮尔曼相关系数使用的是数据样本排位位次值(有时候数据本身就是位次值,有时候数据本身不是位次值,则在计算斯皮尔曼相关系数之前要先计算位次值)。

非参数”的两层含义:

  1. 当X和Y的关系是由任意单调函数描述的,则它们是完全皮尔逊相关的;反过来看,皮尔逊相关系数只能给出由线性方程描述的X和Y的相关性
  2. 斯皮尔曼不需要先验知识(也就是说,除了数据本身不需要知道其它参数,比如说关于数据的分布的先验信息)便可以准确获取X和Y的采样概率分布之间的相关性

(2)适用情况

  1. 数据展现的是非线性关系,或者不是正态分布的
  2. 至少有一方数据是序数类型(ordinal)而非数值类型

例如考察两个球队在历年联赛中的战绩之间的关系,得到的数据可能是这样的:A队在2010~2020年间的联赛排名为{1,2,4,5,…,2}, B队在2010~2020年间的联赛排名为{2,1,3,6,…,4}。这两个数据就是序数类型的数据,考察它们的相关性你使用皮尔逊相关系数就不妥当

  1. 数据中有明显的异常值

与皮尔逊相关不同,斯皮尔曼相关对于异常值不太敏感,因为它基于排序位次进行计算,实际数值之间的差异大小对于计算结果没有直接影响

(3)表达式

ρ = 1 n ∑ i = 1 n ( R ( x i ) − R ( x ) ‾ ) ⋅ ( R ( y i ) − R ( y ) ‾ ) ( 1 n ∑ i = 1 n ( R ( x i ) − R ( x ) ‾ ) 2 ) ⋅ ( 1 n ∑ i = 1 n ( R ( y i ) − R ( y ) ‾ ) 2 ) \rho=\frac{\frac{1}{n}\sum_{i=1}^{n}\left(R(x_{i})-\overline{R(x)})\cdot(R(y_{i})-\overline{R(y)}\right)}{\sqrt{\left(\frac{1}{n}\sum_{i=1}^{n}\left(R(x_{i})-\overline{R(x)}\right)^{2}\right)\cdot\left(\frac{1}{n}\sum_{i=1}^{n}\left(R(y_{i})-\overline{R(y)}\right)^{2}\right)}} ρ=(n1i=1n(R(xi)R(x))2)(n1i=1n(R(yi)R(y))2) n1i=1n(R(xi)R(x))(R(yi)R(y))

  • R ( x ) R(x) R(x) R ( y ) R(y) R(y)分别是x和y的位次

(4)代码实现

import numpy as np
from scipy import stats  # 基于scipy
 
stats.spearmanr([3,5,1,6,7,2,8,9,4], [5,3,2,6,8,1,7,9,4])  # 确定顺序的

rng = np.random.default_rng()
x2n = rng.standard_normal((100, 2))
stats.spearmanr(x2n)  # 随机数序列的
import pandas as pd  # 基于pandas
import numpy as np
X=pd.Series([3,5,1,6,7,2,8,9,4])
Y=pd.Series([5,3,2,6,8,1,7,9,4])
rho = X.corr(Y,method='spearman')
print(rho)

2、皮尔逊相关系数

  • 最常用的相关,通常用 r r r表示
  • 衡量两个随机变量间的线性关系(线性关联度)

(1)数学表达式

定义为:两个变量之间的协方差和标准差之积的商
r = ∑ i = 1 n ( x i − X ˉ ) ( y i − Y ˉ ) ∑ i = 1 n ( x i − X ˉ ) 2 ∑ i = 1 n ( y i − Y ˉ ) 2 r=\frac{\sum_{i=1}^{n}(x_{i}-\bar{X})(y_{i}-\bar{Y})}{\sqrt{\sum_{i=1}^{n}(x_{i}-\bar{X})^{2}}\sqrt{\sum_{i=1}^{n}(y_{i}-\bar{Y})^{2}}} r=i=1n(xiXˉ)2 i=1n(yiYˉ)2 i=1n(xiXˉ)(yiYˉ)
X ˉ \bar{X} Xˉ Y ˉ \bar{Y} Yˉ分别是两个样本的均值

(2)数学性质

1)对称性


因为每个样本的协方差与标准差不变,所以其具有对称性

2)位移不变性

由于在皮尔逊相关计算(不管是总体的、还是样本的)中,分子(两者的协方差)和分母(各自的方差)都通过减去均值(中心化,或者均值归一化)将均值的影响消除掉了,因此X和Y的均值的变化不会影响两者之间的皮尔逊相关系数

3)尺度不变性

分别将X与Y乘以一个不变的系数,两样本间的皮尔逊系数不变

(3)结果分析


1)左: r = 1 r=1 r=1完全正相关;中:为 r = 0 r=0 r=0线性不相关;右: r = − 1 r=-1 r=1完全负相关
image.png
2)上图为不完全相关
3)注:皮尔逊中, r = 0 r=0 r=0仅能说明两个变量间没有线性关系,可能还存在其他相关性:

如上图,可能存在非线性关系
4)image.png

(4)代码实现

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import pearsonr
from scipy.optimize import curve_fit

# 生成随机数
np.random.seed(0)
x = np.random.rand(100)
y = 2 * x + 1 + np.random.randn(100) * 0.2

# 计算皮尔逊相关系数
correlation_coefficient, _ = pearsonr(x, y)

# 定义线性函数
def linear_function(x, a, b):
    return a * x + b

# 使用curve_fit拟合数据
params, covariance = curve_fit(linear_function, x, y)

# 绘制散点图和拟合曲线
plt.scatter(x, y, label='Data')
plt.plot(x, linear_function(x, *params), color='red', label='Fit: {:.2f}x + {:.2f}'.format(*params))
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot with Fitted Line\nCorrelation coefficient = {:.2f}'.format(correlation_coefficient))
plt.legend()
plt.grid(True)
plt.show()

3、肯德尔相关系数

(1)基本概念

  • 使用 τ \tau τ表示
  • 基于样本数据对之间的关系来进行相关系数的强弱的分析,数据对可以分为一致对(Concordant)和分歧对(Discordant)
  • 需要首先计算一致对与分歧对
1)一致对与分歧对

一致对:
两个变量的这一对样本值取值的相对关系一致,可以理解为有相同的符号,即
分歧对:
这一对样本值取值的相对关系不一致,即

2)前提条件

使用肯德尔系数时,应满足以下两个假设

  1. 变量数据是有序的( ordinal) 或者是连续的(continuous)

有序尺度(Ordinal scales)的数据通常用于以数值的方式来衡量非数值的概念,例如满意度,幸福度等等,还有像成绩排名啊、比赛名次啊之类的。而连续尺度的数据就勿需解释了,常见的温度啊、体重啊、收入啊等等都(或严格、或近似)算是连续尺度的数据。

  1. 两个变量的数据之间应该遵循单调关系( monotonic relationship)

这个单调关系是一个统计意义上的,或者说一种趋势上的,而非严格的单调。如下如所示。左图和中图都呈现一种近似单调的关系,而右图则不是,因为右图的左半部分和右半部分的趋势是相反的。

3)适用情况

数据样本比较小,而且存在并列排位(tied ranks,比如说小明的历史成绩和英语成绩排名都是第8名)时,肯德尔相关系数是比斯皮尔曼相关系数更合适的一个相关性衡量指标。
例如:

  1. 学生的考试成绩分级 (A, B, C…) 和他平均每天学习所投入的时间分级 (<2 hours, 2–4 hours, 5–7 hours…)时间的相关性
  2. 顾客满意度 (比如说:非常满意,比较满意,一般。。。) 以及递送时间 (< 30 Minutes, 30 minutes — 1 Hour, 1–2 Hours etc)

(2)表达式及代码实现

有两个计算公式,一个称为Tau-c,另一个称为Tau-b。两者的区别是Tau-b可以处理有相同值的情况,即并列排位(tied ranks)

1)Tau-a


n表示样本个数。如上所述,肯德尔相关系数是基于数据对来进行分析的,n个样本每两两组队所得到的组队数就是,Tau-a的分母即来自于此。分子中c和d则分别代表一致对和分歧对的个数

from scipy.stats.stats import kendalltau
 
dat1 = np.array([3,5,1,9,7,2,8,4,6])
dat2 = np.array([5,3,2,6,8,1,7,9,4])
fig,ax = plt.subplots()
ax.scatter(dat1,dat2)
kendalltau(dat1,dat2)

>>> KendalltauResult(correlation=0.39, pvalue=0.18)
2)Tau-b

当原始数据中存在并列排位时,则用以下公式能够给出更准确的分析结果。

其中c和d则分别代表一致对和分歧对的个数, t x t_x tx t y t_y ty则分别表示数据X中的并列排位个数数据Y中的并列排位个数
注:如果是同时发生在X和Y中并列排位,则既不计入 t x t_x tx,也不计入 t y t_y ty

from scipy.stats.stats import kendalltau
 
dat1 = np.array([3,5,1,6,7,2,8,8,4])
dat2 = np.array([5,3,2,6,8,1,7,8,4])

print('kendalltau(dat1,dat2) =  {0}'.format(kendalltau(dat1,dat2)))

>>>kendalltau(dat1,dat2) =  KendalltauResult(correlation=0.6857142857142857, pvalue=0.011424737055271894)

  • 43
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我可以为您介绍计算ICC相关性系数的Java代码实现方法。您可以使用Apache Commons Math库中的StatisticalAnalysis类来计算。以下是示例代码: ``` import org.apache.commons.math3.stat.StatUtils; import org.apache.commons.math3.stat.correlation.Covariance; import org.apache.commons.math3.stat.correlation.KendallsCorrelation; import org.apache.commons.math3.stat.correlation.PearsonsCorrelation; import org.apache.commons.math3.stat.correlation.SpearmansCorrelation; public class ICCCalculator { // 计算ICC的方法 public double calculateICC(double[][] data) { // 计算rater间的平均值,得到每个item的平均得分 double[] itemMeans = StatUtils.mean(data); // 计算rater之间的协方差 Covariance cov = new Covariance(data); double raterVariance = cov.getTrace() / data.length; // 计算item之间的协方差 double[] itemVariances = new double[data[0].length]; for (int i = 0; i < data[0].length; i++) { double[] column = getColumn(data, i); itemVariances[i] = StatUtils.variance(column); } double itemVariance = StatUtils.mean(itemVariances); // 计算ICC double icc = (raterVariance - (itemVariance / data[0].length)) / raterVariance; return icc; } // 获取矩阵的某一列 private double[] getColumn(double[][] data, int columnIndex) { double[] column = new double[data.length]; for (int i = 0; i < data.length; i++) { column[i] = data[i][columnIndex]; } return column; } // 测试代码 public static void main(String[] args) { double[][] data = {{2, 3, 4}, {3, 4, 5}, {4, 5, 6}, {5, 6, 7}}; ICCCalculator iccCalculator = new ICCCalculator(); double icc = iccCalculator.calculateICC(data); System.out.println("ICC: " + icc); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值