皮尔逊、斯皮尔曼、肯德尔相关系数python实现

一、肯德尔系数

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(n1)2i<jσ(xixj)σ(yiyj)
其中,
σ ( 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=01,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)
  • 3
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值