背景与概述
领域中的需求
在数据分析实战中,多列标注数据往往来自不同标注者,评估者的标签可能存在偏差。此时,简单的百分比一致性会受到类别分布的影响,难以区分偶然一致与系统性一致。因此,Cohen's Kappa作为一个对偶合并一致性的度量,能够在考虑随机一致性的基础上衡量两组评分的差异程度。
当需要比较两份数据框(DataFrame)中不同列的标注结果时,我们希望得到一个相似度矩阵,其中矩阵的行表示第一份DataFrame的列,列表示第二份DataFrame的列,矩阵元素给出对应列之间的Kappa分数。这就把“单列对比”扩展为“多列对比”的数据分析任务。
Cohen's Kappa的定义与性质
Cohen's Kappa的核心在于对随机一致性进行校正,公式为 κ = (p0 - pe) / (1 - pe),其中 p0 是观测一致性,pe 是无偏随机一致性。该指标的取值范围通常在 -1 到 1 之间,越接近1表示越强的一致性,接近0表示与随机水平接近,负值表示一致性低于随机。
在计算多对比矩阵时,我们需要确保对不同列的标签空间有相同的类别集合,否则Kappa计算会受类别对齐影响。常见做法是对所有数据进行统一的类别映射,或者在调用 cohen_kappa_score 时传入相同的标签集合。
快速计算Cohen's Kappa相似度矩阵的思路
矩阵化任务的目标
本任务的目标是从两份DataFrame中提取列向量,逐对计算 Cohen's Kappa,并将结果整理成一个矩阵,方便后续统计和可视化分析。
两份DataFrame的结构设定
假设两份DataFrame的行数相同,列数分别为 m 和 n,且每个单元包含一个类别标签(离散型数据)。若存在缺失值,需要在计算前对该对齐的观测进行NA处理,通常是删除含NA的样本。
边界条件与假设
为了获得稳定的结果,建议轻量化地统一类别标签的集合,避免因缺失类别导致的偏差。对于样本量较小的列对,κ值的置信区间会较宽,因此需要结合领域经验进行解读。
Python实现:快速计算两个DataFrame的Cohen's Kappa相似度矩阵
准备工作与依赖
在开始实现前,确保环境中已经安装了pandas和scikit-learn,以及一个现代的Python运行环境。你可以使用以下命令安装依赖:pip install pandas scikit-learn。
接着,导入需要的库并准备两份DataFrame,确保它们的行数相同,以便进行一对一的列对列比较。下面的实现展示了一个清晰的函数接口,便于复用。
核心算法思路
核心思路是对两个DataFrame的列组合逐对执行 cohen_kappa_score,并在一个结果矩阵中记录每对的κ值。为了保证鲁棒性,我们在计算前对样本进行缺失值过滤,只保留两列的公共观测。
若两列的类别分布完全不出现重叠,结果应返回 NaN,以反映该对无法进行κ统计的情况。实现中也可以增加一个可选的英文参数,用于指定类别标签的全集,以确保跨列一致性。
代码示例与逐步解析
完整实现
import pandas as pd
import numpy as np
from sklearn.metrics import cohen_kappa_score
def compute_kappa_matrix(df1: pd.DataFrame, df2: pd.DataFrame, weights=None, labels=None) -> pd.DataFrame:
"""
计算两个 DataFrame 的 Cohen's Kappa 相似度矩阵。
行索引为 df1 的列名,列索引为 df2 的列名。
- df1: (n_rows, m) DataFrame
- df2: (n_rows, n) DataFrame
- weights: 你希望使用的加权方式,默认为 None(无权重)
- labels: 统一的类别集合,用于跨列对齐,默认为 None
"""
if df1.shape[0] != df2.shape[0]:
raise ValueError("两个 DataFrame 必须具有相同的行数。")
m = df1.shape[1]
n = df2.shape[1]
result = np.empty((m, n), dtype=float)
result.fill(np.nan)
for i, c1 in enumerate(df1.columns):
x = df1[c1]
for j, c2 in enumerate(df2.columns):
y = df2[c2]
mask = x.notna() & y.notna()
if mask.sum() == 0:
result[i, j] = np.nan
else:
if labels is not None:
score = cohen_kappa_score(x[mask], y[mask], labels=labels, weights=weights)
else:
score = cohen_kappa_score(x[mask], y[mask], weights=weights)
result[i, j] = score
return pd.DataFrame(result, index=df1.columns, columns=df2.columns)
# 示例
# df1 = pd.DataFrame({'A':[1,2,1,0], 'B':[0,1,0,0]})
# df2 = pd.DataFrame({'X':[1,2,1,1], 'Y':[0,0,0,0]})
# print(compute_kappa_matrix(df1, df2))
逐步讲解
在以上实现中,输入校验确保两个 DataFrame 行数一致,避免无意义的对比。随后,双重循环逐对比较 df1 的每一列与 df2 的每一列,利用 cohen_kappa_score 计算 κ 值。
对每对样本,先执行 缺失值过滤,只保留同时有标签的观测,确保结果的可解释性。最后,将计算得到的 κ 值放入一个 NumPy 矩阵,再转为 DataFrame,方便查看行列对应关系。
应用场景与案例分析
医疗标注一致性评估
在放射学或病理学的标注任务中,两名标注者或两个模型的输出会对同一组影像或病例作出离散类别标签。使用本方法得到的 Cohen's Kappa相似度矩阵,可以快速识别哪些列对的标注一致性较高,哪些需要重新标注或再培训模型。
将结果可视化为热力图时,可以帮助领域专家定位潜在的系统性偏差,从而在后续分析中针对性地改进标签体系。鲁棒的 κ 矩阵还可以作为质量控制的一部分,用于跨实验室的可重复性评估。
问卷与文本编码的一致性分析
当问卷中多个问题需要人工编码,且不同问卷之间存在不同编码方式时,跨列对比的 κ 矩阵可以揭示哪些问题的标注存在较大差异。
在文本编码任务中,>如情感等级或主题标签的分级,加权 κ 能反映更高层级的标签差异对相似度的影响,帮助评审团队调整标注标准。


