【卡方检验(Chi-Squared Test)的原理简介】

news2024/11/15 22:52:18

文章目录

  • 卡方检验(Chi-Squared Test)的原理简介
    • 1. 卡方检验的流程
    • 借助scipy进行卡方检验
    • 3 连续变量的卡方检验
    • 4 借助sklearn进行卡方检验特征筛选

卡方检验(Chi-Squared Test)的原理简介

在一般情况下,卡方检验是针对于离散变量的独立性检验,卡方检验的零假设为两个离散变量相互独立。很明显,如果我们将其用于标签和特征的判别,就能借此判断某特征和标签是不是独立的,如果是,则说明特征对标签的预测毫无帮助。因此在很多时候,卡方检验都是非常重要的剔除无关特征的方法。

1. 卡方检验的流程

下面我们来看看卡方检验的具体流程:

假设我们有一组数据,想要确定性别和对某一问题的支持是否存在相关性。

Step1. 提出假设

假设检验的过程往往是采用了类似“反证法”的方法进行论证,例如如果我想证明这枚硬币是质地均匀的,那么在论证之前,我需要提出一个相反的假设,即这枚硬币有问题、质地不均匀,该假设会被记为𝐻0,也就是所谓的零假设。当然既然是假设,就肯定有假设不成立的时候,此时假设结论的对立假设就是这枚硬币没有问题、是质地均匀的,该假设会被记为𝐻1,也被称为备择假设或者对立假设

目前假设情况如下:
H0: 性别和对某一问题的支持不存在相关性
H1:性别和对某一问题的支持存在相关性

Step2. 采集数据

import pandas as pd

data = {
    '支持': [80, 60],
    '反对': [50, 70],
    '无意见': [20, 30]
}

df = pd.DataFrame(data, index=['男性', '女性'])
print(df)

运行这段代码将生成如下的数据表:
在这里插入图片描述

Step 3.设计统计量

支持反对无意见性别_all
男性805020150
女性607030160
态度_all14012050310

态度的取值分布如下:
P ( 态度 = 支持) = 140 310 ≈ 0.452 P(态度=支持)= \frac {140} {310}\approx0.452 P(态度=支持)=3101400.452
P ( 态度 = 反对) = 120 310 ≈ 0.387 P(态度=反对)= \frac {120} {310}\approx0.387 P(态度=反对)=3101200.387
P ( 态度 = 无意见) = 50 310 ≈ 0.161 P(态度=无意见)= \frac {50} {310}\approx0.161 P(态度=无意见)=310500.161
同时,性别的取值分布如下:
P ( 性别 = 男性) = 150 310 ≈ 0.484 P(性别=男性) = \frac{150} {310}\approx0.484 P(性别=男性)=3101500.484
P ( 性别 = 女性) = 160 310 ≈ 0.516 P(性别=女性) = \frac{160} {310}\approx0.516 P(性别=女性)=3101600.516
现依据零假设,性别和态度相互独立,因此对于任意一名被调查者,同时性别=男性且态度=支持的概率为:
𝑃(性别=男性,态度=支持)=𝑃(性别=男性)∗𝑃(态度=支持)=0.484∗0.452=0.219
Notes:根据联合概率计算公式,当A、B两个随机变量相互独立时,𝑃(𝐴,𝐵)=𝑃(𝐴)∗𝑃(𝐵)
而目前,总共有310名被调查者,因此在零假设的情况下,性别=男性且态度=支持的被调查者总数期望为:
𝐸男性,支持=𝑃(性别=男性,态度=支持)∗310=0.219*310=68
而真实的统计结果是性别=男性且态度=支持总被调查者有80人,和期望人数有些差异,很明显,当实际人数和期望人数的差异越大,我们就越有理由怀疑零假设。但这种差异是不能通过性别和态度的一组取值结果来判定,我们还需要进一步查看列联表中其他位置的期望频数

支持反对无意见
男性685824
女性726226

对比统计频数表:

支持反对无意见
男性805020
女性607030

为了衡量二者的差异,我们可以构造如下统计量:
X 2 = ∑ i = 1 m ∑ j = 1 n ( O i , j − E i , j ) 2 E i , j \mathcal{X}^2 = \sum_{i=1}^{m}\sum_{j=1}^{n}\frac{(O_{i,j}-E_{i,j})^2}{E_{i,j}} X2=i=1mj=1nEi,j(Oi,jEi,j)2
其中i、j代表列联表的行和列,𝑂𝑖,𝑗表示i行j列的观测值(observe)、𝐸𝑖,𝑗表示期望值。而此处的X 就是卡方值,也就是卡方检验中的统计量。我们可以通过如下方式进行卡方值的计算:
在这里插入图片描述
对于二维列联表来说,自由度就是(𝑚−1)∗(𝑛−1)
,行数-1和列数-1的乘积:
(2-1)*(3-1)=2

借助scipy进行卡方检验

当然,上述过程我们也可以通过scipy快速执行,这里我们需要调用scipy模块下的stats模块,并借助其中chi2_contingency函数完成相关计算:

from scipy import stats
stats.chi2_contingency(observed = df)

在这里插入图片描述
chi2_contingency函数返回了四个结果,分别是卡方值、概率值、自由度以及期望频数表,和我们此前手动计算结果不完全一致,这可能是手动计算时四舍五入了,下面由计算机手动计算

需要注意的是,这里的p值既是事件发生的概率,同时也是我们后续在进行特征筛选时的一个评分,类似相关系数,p值越小说明越不独立,也就是说明这两个变量关联性越强。当然,除了p值意外,卡方值也可以作为评估关联性强弱的评分,卡方值越大、p值越小、不相关的假设越不成立、变量越相关。

import pandas as pd

data = {
    '支持': [80, 60],
    '反对': [50, 70],
    '无意见': [20, 30]
}

df = pd.DataFrame(data, index=['男性', '女性'])
print(df)

在这里插入图片描述
对df表按行按列汇总

df_count_all = df.copy()

df_count_all.loc['态度-all'] = df.sum(0)
df_count_all['性别-all'] = df_count_all.sum(1)
df_count_all

在这里插入图片描述
计算期望频数表。对于每个单元格,期望频数的计算应该是(性别_𝑎𝑙𝑙[𝑖]/𝑡𝑜𝑙)∗(态度_𝑎𝑙𝑙[𝑗]/𝑡𝑜𝑙)∗𝑡𝑜𝑙
,等于性别_𝑎𝑙𝑙[𝑖]∗态度_𝑎𝑙𝑙[𝑗]/𝑡𝑜𝑙

from itertools import product
性别_all = df_count_all.loc[:,'性别-all'].copy()
态度_all = df_count_all.loc[ '态度-all',:].copy()
for i, j in product(range(2), range(3)):
    Eij = 性别_all[i] * 态度_all[j] / tol
    df_temp.iloc[i, j] = Eij

在这里插入图片描述
在这里插入图片描述

至此,卡方值和chi2_contingency计算一样,我们完成了卡方值的手动计算流程。

3 连续变量的卡方检验

接下来,我们就可以考虑借助sklearn中的相关函数,通过卡方检验来进行特征筛选。不过这里需要注意的是,通常来说卡方检验是作用于离散变量之间的独立性检验,但sklearn中的卡方检验只需要参与检验的其中标签是离散特征即可,即sklearn中的卡方检验不仅可以作用于两个离散变量、还可以作用于连续变量和离散变量之间,因此我们这里需要补充介绍关于连续变量与离散变量之间的卡方检验计算流程,而在连续变量和离散变量的卡方检验中,自由度是离散变量类别数-1,也就是2-1=1

# 生成随机的连续变量和二分类变量
np.random.seed(0)
continuous_variable = np.random.rand(10)
binary_variable = np.random.choice([0, 1], size=10)

# 创建包含连续变量和二分类变量的DataFrame
df = pd.DataFrame({'ContinuousVariable': continuous_variable, 'Binaryariable': binary_variable})

# 打印DataFrame
print(df)

在这里插入图片描述
在这里插入图片描述

但需要注意的是,连续变量的取值毕竟不是频数结果,最终的卡方值会严重受到连续变量的量纲影响,而这种影响对统计推断而言是无意义的。因此,在实际进行连续变量的卡方检验过程中,建议先对原始变量进行标准化处理,该过程会将所有连续变量取值放缩至类似水平,同样也会将p值和卡方值放缩至同样水平,然后我们在单独针对连续变量进行BestK筛选,而不建议同时比较连续变量和离散变量的K值然后在一个流程中进行筛选(因为连续变量的p值和卡方值没有绝对大小的意义)

4 借助sklearn进行卡方检验特征筛选

sklearn其实是采用类似连续变量的卡方检验流程来进行的离散变量卡方检验。其实这也并不奇怪,对于sklearn来说,默认是不区分连续变量和离散变量的。并且计算过程中的自由度也不再是列联表行数-1和列数-1相乘的结果,而是标签取值水平-1。那就是可以统一自由度。原生的卡方检验的自由度是同时受到两个离散变量类别个数影响,此时带入不同离散变量时自由度可能不同,而不同的自由度将影响评分数值绝对值的有效性(自由度越高对评分大值容忍度就越高)

我们尝试借助sklearn进行基于卡方检验的特征筛选。该过程同样涉及评分函数和筛选评估器两部分,此处筛选评估器仍然选用SelectKBest,而卡方检验的评分函数是chi2:在最终的SelectKBest筛选过程,实际上是按照卡方值的大小,筛选卡方值最大的k个特征(不是按照p值进行筛选)。根据卡方检验的计算流程,卡方值不会存在负数情况,并且卡方值越大、说明变量之间关联关系越强 。相关实现流程如下

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
import numpy as np

# 加载示例数据集
iris = load_iris()
X, y = iris.data, iris.target
X = pd.DataFrame(X,columns=iris.feature_names)

在这里插入图片描述

# 使用卡方检验选择前两个最佳特征
KB_chi2 = SelectKBest(chi2, k=2)
X_new = KB_chi2.fit_transform(X, y)#输入特征减少到仅包含通过卡方检验选择出的前2个特征。

在这里插入图片描述

KB_chi2.scores_
#KB_chi2.scores_是指使用chi2统计测试后,每个特征的得分。
#在SelectKBest中,使用chi2统计测试对每个特征进行评分,表示该特征与目标变量之间的相关性或关联程度。
#得分越高表示特征与目标变量之间的关联程度越高。

在这里插入图片描述

KB_chi2.pvalues_#KB_chi2.pvalues_指的是使用chi2统计测试后,每个特征的p值。
#在统计学中,p值表示观察到的数据与原假设一致的概率。
#在特征选择中,p值可以用来衡量特征与目标变量之间的相关性。较低的p值表示特征与目标变量之间的关联性较高。

在这里插入图片描述

def SelectName(Select, KBest=True):
    """
    根据特征筛选评估器进行列名称输出函数
    
    :param Select: 训练后的特征筛选评估器
    :param KBest: 是否是挑选评分最高的若干个特征
    
    :return:保留特征的列名称
    """
    if KBest == True:
        K = Select.k
    else:
        l = np.array(range(Select.n_features_in_))
        K = (l > np.percentile(l, 100 - Select.percentile)).sum()
    
    threshold = sorted(Select.scores_, reverse=True)[K-1]
    
    col_names = []

    for score, col in zip(Select.scores_, Select.feature_names_in_):
        if score >= threshold:
            col_names.append(col)
            
    return col_names
SelectName(KB_chi2)

在这里插入图片描述
可以看到,前两名特征跟我们之前看到的一样,至此,卡方检验原理介绍完毕!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1376941.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android Retrofit使用详情

一、 Retrofit是什么 Retrofit是Android用来接口请求的网络框架,内部是基于OkHttp实现的,retrofit负责接口请求的封装,retrofit可以直接将接口数据解析为Bean类、List集合等,直接简化了中间繁琐的数据解析过程 二、 Retrofit的简单…

kylin3集群问题和思考(单机转集群)

目录 单机改集群注意事项 问题 思考 建议 单机改集群注意事项 之前是使用的单机版,但后面查询压力过大,一个方案是改成集群。 由于是同一个集群的,元数据没有变化,所以,直接将原本的kylin使用scp的方式发送到其他节…

数据结构04附录01:字符串大写转小写[C++]

图源:文心一言 上机题目练习整理~🥝🥝 本篇作为字符串的代码补充,提供了3种(差别并不大)解法以及函数的详细解释,供小伙伴们参考~🥝🥝 前文:🌸…

基于SSM的汽车客运订票系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

漏油控制器有用吗?漏油监测器多少钱一个?

漏油控制器也可以被称作漏油监测器、漏油传感器,是漏油检测系统里的一部分,一般是和漏油检测绳组合在一起使用,用来检测油罐、输油管道、油类化工厂等场合是否有油料泄露。很多人刚开始可能会觉得难以置信,这么一个小东西就可以检…

Sqoop入门指南:安装和配置

Sqoop是一个强大的工具,用于在Hadoop和关系型数据库之间高效传输数据。在本篇文章中,将深入探讨如何安装和配置Sqoop,以及提供详细的示例代码。 安装Java和Hadoop 在开始安装Sqoop之前,首先确保已经成功安装了Java和Hadoop。Sqo…

魔众文库新版本:自动化功能让文库管理更轻松!

VIP界面升级,文档文本自动解析、虚拟数量升级,小程序自适应 [新功能] Values 组件新增 countFixed 属性,固定显示数量 [新功能] 后台文库管理分页调整为 10,100,,100 [新功能] 后台文库管理增加虚拟数量批量修改功能…

Golang基础入门及Gin入门教程(2024完整版)

Golang是Google公司2009年11月正式对外公开的一门编程语言,它不仅拥有静态编译语言的安全和高性能,而 且又达到了动态语言开发速度和易维护性。有人形容Go语言:Go C Python , 说明Go语言既有C语言程序的运行速度,又能达到Python…

抖店开通后下一步做什么?最新教程如下,手把手教你设置店铺功能

我是王路飞。 上篇文章给你们说了下2024年最新的抖店开通、入驻流程,还没看到的可以去看下。 既然店铺已经开通了,那接下来自然就是运营店铺了。 很多新手小白也是开店很积极,但真正开始运营的时候就抓瞎了,不知道店铺开通后下…

【深入挖掘Java技术】「源码原理体系」盲点问题解析之HashMap工作原理全揭秘(下)

盲点问题解析之HashMap工作原理全揭秘 承接上文创建HashMap对象参考容量(capacity)Hashmap内部有一个机制扩容阈值(threshold)负载因子(loadFactor) HashMap存储元素的过程HashMap的put方法JDK8的扩容机制N…

使用curl命令在Linux上进行HTTP请求

在Linux系统中,curl是一个非常强大的命令行工具,用于发送各种类型的HTTP请求。通过简单的命令,你可以发送GET、POST、PUT、DELETE等请求,以及设置请求头、处理响应等。以下是一些使用curl进行HTTP请求的常见用法和示例。 1. 发送…

(十)IIC总线-PCF8591-ADC/DAC

文章目录 IIC总线篇起始,终止信号应答信号发送,读取数据IIC通讯规则 PCF8591-ADC-DAC篇特性一般说明地址Control byte(控制字)简单了解一下DAC电阻分隔链应用为王DAC的应用ADC的应用ADC采集特点ADC读模式 ADC现象演示DAC现象演示 …

八、Stm32学习-USART-中断与接收数据包

1.通信接口 全双工就是数据的收和发可以同时进行;半双工就是数据的收和发不能同时进行。 异步时钟是设备双方需要约定对应的波特率;同步时钟是设备双方有一根时钟线,发送或接收数据是根据这根时钟线来的。 单端电平是需要共GND;…

uniapp 打包成 apk(原生APP-云打包)免费

修改APP配置 根据需求,修改 manifest.json 配置,常见的修改有: 应用名称,应用版本名称,应用版本号 升级版本时,应用版本名称和应用版本号必须高于上一版的值 应用图标 点浏览选择png格式的图片后&#x…

【VPN技术】简述几种常见VPN技术并比较其异同点

VPN技术是一种可以在公共网络上建立加密通道的技术,通过这种技术可以使远程用户访问公司内部网络资源时,实现安全的连接和数据传输。 下面以四种常见的VPN技术,分别介绍各自的特点和适用场景,然后进行异同点的比较。 PPTP&#x…

微信私域,如何实现高效回复客户消息?

随着微信用户数量的增加,人们的需求也越来越多。其中有一项就是全天候及时回复消息,不让好友等待。当企业拥有多个微信号进行私域流量管理时,如何做到及时回复客户消息呢? 下面给大家分享高效回复客户消息的秘诀,帮助提…

highlight.js 实现搜索关键词高亮效果 ,显示匹配数量及切换显示功能

先看效果&#xff1a; 更新&#xff1a;增加切换显示 折腾了老半天&#xff0c;记录一下 注意事项都写注释了 代码&#xff1a; <template><div class"absolute-lt wh-full overflow-hidden p-10"><div style"width: 200px"><el-…

研究了Web版Photoshop,提升自己=提升价值

Adobe 发布了Web版 Photoshop&#x1f517;&#xff0c;它是使用 WebAssembly、web components、P3 颜色等 Web 技术构建的。本文就来研究一下网页版 Photoshop 上有趣又有用的 CSS 知识&#xff01; Photoshop 旧 Logo 首先&#xff0c;在浏览器控制台中使用了 Photoshop 的 …

【数字人】9、DiffTalk | 使用扩散模型基于 audio-driven+对应人物视频 合成说话头(CVPR2023)

论文&#xff1a;DiffTalk: Crafting Diffusion Models for Generalized Audio-Driven Portraits Animation 代码&#xff1a;https://sstzal.github.io/DiffTalk/ 出处&#xff1a;CVPR2023 特点&#xff1a;需要音频对应人物的视频来合成新的说话头视频&#xff0c;嘴部抖…

基于python的Hurst计算预测未来发展趋势(长时序栅格影像)

1.Hurst指数反映了时间序列长期记忆性的程度&#xff0c;即过去的信息对未来的影响程度。Hurst指数的取值范围为0到1之间&#xff0c;当Hurst指数等于0.5时&#xff0c;时间序列被认为是一种随机漫步&#xff0c;即具有随机性&#xff1b;当Hurst指数大于0.5时&#xff0c;时间…