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 则可以认为两个序列具有一定的相关性。
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)
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)