杰瑞科技汇

Python中contingency是什么?如何使用?

在统计学和数据科学中,Contingency Table(列联表) 是一种用来展示两个或多个分类变量之间频率分布的表格,它的核心作用是帮助我们分析这些变量之间是否存在关联性。

Python中contingency是什么?如何使用?-图1
(图片来源网络,侵删)

在 Python 中,处理列联表和相关分析的工具主要来自以下几个库:

  1. Pandas: 用于创建和操作列联表。
  2. SciPy (stats module): 用于执行统计检验,判断变量是否独立。
  3. Seaborn: 用于可视化列联表(如热图)。

下面我将分步介绍如何使用这些工具。


使用 Pandas 创建列联表

Pandas 提供了非常方便的函数来创建列联表,最常用的是 crosstab()pivot_table()

示例数据

我们先创建一个示例数据集,来研究性别和吸烟习惯之间的关系。

Python中contingency是什么?如何使用?-图2
(图片来源网络,侵删)
import pandas as pd
import numpy as np
# 创建一个示例 DataFrame
data = {
    'Gender': ['Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Male', 'Female'] * 10,
    'Smoking_Status': ['Smoker', 'Non-Smoker', 'Non-Smoker', 'Smoker', 'Smoker', 'Non-Smoker', 'Non-Smoker', 'Non-Smoker', 'Smoker', 'Smoker'] * 10
}
df = pd.DataFrame(data)
print("原始数据前10行:")
print(df.head(10))

a) pd.crosstab()

这是创建列联表最直接、最常用的方法。

# 创建一个简单的列联表
# index: 行变量, columns: 列变量
contingency_table = pd.crosstab(index=df['Gender'], columns=df['Smoking_Status'])
print("\n使用 pd.crosstab() 创建的列联表:")
print(contingency_table)

输出:

使用 pd.crosstab() 创建的列联表:
Smoking_Status  Non-Smoker  Smoker
Gender                          
Female                50      50
Male                  50      50

这个表格显示了每个性别中,吸烟者和非吸烟者的人数。

b) pd.pivot_table()

pivot_table 更灵活,可以用于更复杂的聚合,但创建基础的列联表也很方便。

# 使用 pivot_table 创建列联表
# aggfunc='size' 会计算每个组合的出现次数
contingency_table_pt = pd.pivot_table(
    df, 
    index='Gender', 
    columns='Smoking_Status', 
    aggfunc='size', 
    fill_value=0 # 将缺失值填充为0
)
print("\n使用 pd.pivot_table() 创建的列联表:")
print(contingency_table_pt)

输出结果与 crosstab 相同。

c) 添加边际总和

为了更直观地看到总数,我们可以添加行和列的总和。

# margins=True 会添加行和列的总和
contingency_table_with_margins = pd.crosstab(
    index=df['Gender'], 
    columns=df['Smoking_Status'], 
    margins=True, 
    margins_name="Total"
)
print("\n带有边际总和的列联表:")
print(contingency_table_with_margins)

输出:

带有边际总和的列联表:
Smoking_Status  Non-Smoker  Smoker    Total
Gender                                    
Female                50      50      100
Male                  50      50      100
Total                100     100      200

使用 SciPy 进行卡方检验 (Chi-Squared Test)

创建列联表后,我们通常想知道这两个变量是否独立。卡方检验 (Chi-Squared Test of Independence) 是最常用的方法。

  • 原假设 (H₀): 两个变量是独立的(即性别与吸烟习惯无关)。
  • 备择假设 (H₁): 两个变量不是独立的(即性别与吸烟习惯有关)。

p-value(p值)小于我们选择的显著性水平(通常是 0.05),我们就可以拒绝原假设,认为两个变量之间存在显著关联。

from scipy.stats import chi2_contingency
# 使用之前创建的列联表(不带边际总和)
contingency_table_for_test = pd.crosstab(index=df['Gender'], columns=df['Smoking_Status'])
# 执行卡方检验
# chi2: 卡方统计量
# p: p值
# dof: 自由度
# expected: 期望频数表(在原假设下期望的值)
chi2, p, dof, expected = chi2_contingency(contingency_table_for_test)
print("\n--- 卡方检验结果 ---")
print(f"卡方统计量: {chi2:.4f}")
print(f"P值: {p:.4f}")
print(f"自由度: {dof}")
print("\n期望频数表:")
print(expected)
# 解释结果
alpha = 0.05
print(f"\n显著性水平 (alpha): {alpha}")
if p < alpha:
    print(f"因为 P值 ({p:.4f}) < {alpha},我们拒绝原假设。")
    print("性别与吸烟习惯之间存在显著关联。")
else:
    print(f"因为 P值 ({p:.4f}) >= {alpha},我们无法拒绝原假设。")
    print("没有足够的证据表明性别与吸烟习惯之间存在关联。")

分析结果: 在我们的示例数据中,因为数据是随机生成的,p-value 会很大(远大于 0.05),我们无法拒绝原假设,认为它们是独立的,如果你修改数据,让男性和女性的吸烟比例有明显差异,p-value 就会变小,从而得出它们存在关联的结论。


使用 Seaborn 进行可视化

“热图”是可视化列联表的最佳方式,颜色深浅可以直观地表示频数的高低。

import seaborn as sns
import matplotlib.pyplot as plt
# 设置绘图风格
sns.set(style="whitegrid")
# 创建热图
plt.figure(figsize=(8, 6))
ax = sns.heatmap(
    contingency_table, 
    annot=True,      # 在格子上显示数值
    fmt='d',         # 数值的格式为整数
    cmap='viridis'   # 颜色映射
)
ax.set_title('Gender vs. Smoking Status (Heatmap)', fontsize=16)
ax.set_xlabel('Smoking Status', fontsize=12)
ax.set_ylabel('Gender', fontsize=12)
plt.show()

这会生成一个热图,让你一眼就能看出各个组合的频数分布。


总结与工作流程

一个完整的关于 "contingency" 的分析流程如下:

  1. 加载数据: 使用 Pandas 将你的数据读入 DataFrame。
  2. 创建列联表: 使用 pd.crosstab() 快速创建两个分类变量的交叉表。
  3. 可视化 (可选但推荐): 使用 seaborn.heatmap() 将列联表绘制成热图,进行初步探索。
  4. 执行统计检验: 使用 scipy.stats.chi2_contingency() 对列联表进行卡方检验,以获得 p-value。
  5. 解释结果: 根据 p-value 和你设定的显著性水平,判断两个变量之间是否存在统计上的显著关联。

核心工具对应关系:

任务 Pandas 函数 SciPy 函数 Seaborn 函数
创建列联表 pd.crosstab() - -
统计检验 - chi2_contingency() -
可视化 - - sns.heatmap()

掌握了这些工具,你就可以在 Python 中熟练地进行分类变量之间的关联性分析了。

分享:
扫描分享到社交APP
上一篇
下一篇