[数学基础知识] Cramér‘s V 相关系数和Python算法实现

1. 什么是Cramér’s V 相关系数

在统计中,Cramér’s V (又称为Cramér’s phi,表示为φc) 是一个衡量两个
分类变量之间关联的度量,它是一个介于0和+1(包括)之间的值, 0表示两个变量无关,1表示完全相关。它是基于Pearson’s chi-squared statistic(皮尔森的卡方统计),由Harald Cramér于1946年发表的。

所以在介绍Cramér’s V 相关系数之前,我们先来了解一下皮尔森的卡方统计。

2. 皮尔森的卡方统计(Pearson’s chi-squared statistic)

2.1 皮尔森的卡方检验(Pearson’s chi-squared test)

是最有名卡方检验之一,最早由卡尔·皮尔逊在1900年发表。

理论不多说了,我们通过一个例子来说明什么是皮尔森的卡方检验。

以下数据来自一个研究关于自闭症和疫苗的关联性的数据。

–表格1–

有自闭症无自闭症总共
打疫苗621440,034440,655
不打疫苗11796,53196,648
总共738536,565537,303

在打疫苗的440,655人中,有自闭症的人有621人。在不打疫苗的96,648中,有自闭症的有117人。那么从这一组数据中,我们能否看出疫苗和自闭症是否有关联呢?
第一步
使用皮尔森的卡方检验,我们首先假设:
H0: 疫苗和自闭症并不关联
H1: 疫苗和自闭症并有关联

如果H0假设成立,那么在打疫苗和不打疫苗的人群中,有自闭症的人数比例应该是一致的。
我们由第三行数据得到,537,303人中有738人患有自闭症,得到患有自闭症的总统比例是 738 / 537 , 303 = 0.001374 738/537,303=0.001374 738/537,303=0.001374。大约是千分之一多一点。

第二部
如果不考虑样本偏差,那么在打疫苗和不打疫苗的人群中,这个比例是一致的,我们就通过计算得到理想状态下打疫苗和不打疫苗两个群体中的自闭症患者人数。
–表格2–

期望值有自闭症无自闭症总共
打疫苗440,655*(738/537,303) =602.8440,655*(536,565/537,303)=440,049.7440,655
不打疫苗96,648*(738/537,303)=132.796,648*(536,565/537,303)=96,515.396,648
总共738536,565537,303

第三步
我们将上面的的计算结果和实际实验数据进行比较,对每个单元格计算出以下统计量 ( 实际值 − 期望值 ) 2 期望值 \frac{(实际值-期望值)^2}{期望值} 期望值(实际值期望值)2,然后对它们求和。

T E S T S T A T = χ S T A T 2 = ∑ 所有单元格 ( O − E ) 2 E TEST_{STAT} = \chi ^2_{STAT} = \sum_{所有单元格}{\frac{(O-E)^2}{E}} TESTSTAT=χSTAT2=所有单元格E(OE)2
= ( 621 − 602.8 ) 602.8 + . . . + ( 96 , 531 − 96 , 515.3 ) 96 , 515.3 = 2.28 =\frac{(621-602.8)}{602.8}+...+\frac{(96,531-96,515.3)}{96,515.3}=2.28 =602.8(621602.8)+...+96,515.3(96,53196,515.3)=2.28
这个结果服从于 χ 2 \chi ^2 χ2分布, 我们可以通过查表得知
P − V a l u e = P ( χ S T A T 2 > = 2.28 ) ) = 0.1309 P-Value=P(\chi^2_{STAT}>=2.28))=0.1309 PValue=P(χSTAT2>=2.28))=0.1309
根据经验值,一般拒绝域取0.05,0.1309>0.05, H0为真。
因此,我们认为没有明显证据证明疫苗和自闭症有联系。

3. Cramér’s V 相关系数

3.1 自由度

Cramér’s V 相关系数是 χ 2 \chi^2 χ2统计量除以卡方检验中的自由度。
所谓自由度与卡方检验中的行和列数有关,如果我们仔细观察上面的表格2,我们会发现其实四个单元格中如果一个单元格的值已经确定,则其他三个单元格的值就都确定了,我们称之自由度为1。
对于卡方检验中的 n n n m m m列的表格其自由度为:
自由度 = ( n − 1 ) ( m − 1 ) 自由度=(n-1)(m-1) 自由度=(n1)(m1)

3.2 计算Cramér’s V 相关系数

在算得卡方统计量的基础上再进行计算的。

C r a m e ˊ r ′ s V = ∑ 所有单元格 ( O − E ) 2 E 统计样本量 ∗ ( m i n ( n , m ) − 1 ) Cramér's V = \frac{\sum_{所有单元格}{\frac{(O-E)^2}{E}}}{统计样本量*(min(n,m)-1)} CrameˊrsV=统计样本量(min(n,m)1)所有单元格E(OE)2
说明

  • 统计样本量是指总体样本条数,以上面卡方统计的例子为例,这个统计样本量是537,303。
  • 卡方统计的n行m列数中较小一个是指卡方统计中使用的这个表格的行列数,在上面例子中,行数是2,列数也是2,那么min(2,2)=2,那min(2,2)-1=1

所以,以上面例子为例,则计算中的分子是537,303*1。
因此,打疫苗和自闭症之间的相关系数是 2.28 / 537 , 303 = 0.0000042 2.28/537,303=0.0000042 2.28/537,303=0.0000042

4. Python代码

直接奉上Python代码。

def calculate_caremers_v(df, column_a, column_b):
  """
  calculate carmer v for the 2 input columns in dataframe
  :param df: Pandas dataframe object 
  :param column_a: 1st column to study 
  :param column_b: 2nd column to study
  :return: Pandas dataframe object with the duplicated recorders removed.  
  """
  if column_a not in df.columns:
    print("the input columne %s doesn't exit in the dataframe."%column_a)
    return None
  elif column_b not in df.columns:
    print("the input columne %s doesn't exit in the dataframe."%column_b)
    return None
  else:
    cross_tb = pd.crosstab(index = df[column_a], columns = df[column_b])
    np_tb = cross_tb.to_numpy()
    min_row_column = min(np_tb.shape[0],np_tb.shape[1])
    colume_sum = np_tb.sum(axis = 0)
    row_sum = np_tb.sum(axis = 1)
    total_sum = np_tb.sum()
    np_mid = np.matmul(row_sum.reshape(len(row_sum),1),
              colume_sum.reshape(1,len(colume_sum)))/total_sum
    new_tb = np.divide(np.power((np_tb-np_mid),np.array([2])),
              np_mid)
            
    return new_tb.sum()/(total_sum*(min_row_column-1))

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小白的逆袭日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值