一、肯德尔系数
1. 定义:
Kendall(肯德尔)系数的定义:n个同类的统计对象按特定属性排序,其他属性通常是乱序的。同序对(concordant pairs)和异序对(discordant pairs)之差与总对数(n*(n-1)/2)的比值定义为Kendall(肯德尔)系数。
肯德尔相关系数可以测量两个随机序列的相关性,肯德尔相关系数被定义为:
τ
=
2
n
(
n
−
1
)
∑
i
<
j
σ
(
x
i
−
x
j
)
σ
(
y
i
−
y
j
)
\tau = \frac{2}{{n(n - 1)}}\sum\limits_{i < j} {\sigma ({x_i} - {x_j})\sigma ({y_i} - {y_j})}
τ=n(n−1)2i<j∑σ(xi−xj)σ(yi−yj)
其中,
σ
(
x
)
=
{
1
,
x
>
0
0
,
x
=
0
−
1
,
x
<
0
\sigma (x) = \left\{ \begin{array}{l}1,{\rm{x > 0}}\\0,{\rm{x = 0}}\\ - 1,{\rm{x < 0}}\end{array} \right.
σ(x)=⎩⎨⎧1,x>00,x=0−1,x<0
x,y 分别表示两个序列,肯德尔相关系数τ 的值域为-1 到 1 之间。当 τ=1时,表示两个序列具有完全一致的相关性;当 τ=-1 时,表示两个序列拥有完全相反的相关性;当 τ=0 时,表示这对序列组是不相关的,而 τ≠0 则可以认为两个序列具有一定的相关性。
2. python实现
from scipy.stats import kendalltau
import numpy as np
def sckendall(a, b):
'''
会与scipy源码中计算的有一定差距
'''
L = len(a)
count = 0
for i in range(L - 1):
for j in range(i + 1, L):
count = count + np.sign(a[i] - a[j]) * np.sign(b[i] - b[j])
kendall_tau = count / (L * (L - 1) / 2)
return kendall_tau
if __name__ == '__main__':
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [3, 7, 2, 1, 4, 8, 6, 10, 5, 9]
kendall_tau_2, p_value = kendalltau(a, b)
kendall_tau = sckendall(a, b)
print(kendall_tau)
print(kendall_tau_2)
二、肯德尔系数、皮尔逊系数、斯皮尔曼系数
2. python实现
import math
from itertools import combinations
#Pearson algorithm
def pearson(x, y):
assert len(x) == len(y) > 0
q = lambda n: len(n) * sum(map(lambda i: i ** 2, n)) - (sum(n) ** 2)
return (len(x) * sum(map(lambda a: a[0] * a[1], zip(x, y))) - sum(x) * sum(y)) / math.sqrt(q(x) * q(y))
#Spearman algorithm
def spearman(x, y):
assert len(x) == len(y) > 0
q = lambda n: map(lambda val: sorted(n).index(val) + 1, n)
d = sum(map(lambda x, y: (x - y) ** 2, q(x), q(y)))
return 1.0 - 6.0 * d / float(len(x) * (len(y) ** 2 - 1.0))
#Kendall algorithm
def kendall(x, y):
assert len(x) == len(y) > 0
c = 0 #concordant count
d = 0 #discordant count
t = 0 #tied count
for (i, j) in combinations(range(len(x)), 2):
s = (x[i] - x[j]) * (y[i] - y[j])
if s:
c += 1
d += 1
if s > 0:
t += 1
elif s < 0:
t -= 1
else:
if x[i] - x[j]:
c += 1
elif y[i] - y[j]:
d += 1
return t / math.sqrt(c * d)
#read in file
GSM = [6,9,3,12,8,7,10,11,2,5,4,1]
LGC = [6,9,3,12,7,8,11,10,2,4,5,1]
kendall_test = kendall(GSM, LGC)
pearson_test = pearson(GSM, LGC)
spearman_test = spearman(GSM, LGC)
print("肯德尔系数:", kendall_test)
print("皮尔逊系数:", pearson_test)
print("斯皮尔曼系数:", spearman_test)