R中的`irr`包计算的加权Kappa是否错误?

问题描述

我发现 irr 包在计算 weighted kappa 时有两个大错误

请告诉我这 2 个错误是否真的存在,或者我误解了某些内容

您可以使用以下示例复制错误

一个错误:需要更正混淆矩阵中的标签类型。

我有 2 对疾病程度评分(从 0 到 100,0 表示健康,100 表示病重)。

label_test.csv中(您可以将数据复制并粘贴到您的磁盘中以进行以下测试):

0
1
1
1
0
14
53
3

pred_test.csv中:

0
1
1
0
3
4
54
6

script_r.R中:

library(irr)
label <- read.csv('label_test.csv',header=FALSE)
pred <- read.csv('pred_test.csv',header=FALSE)

kapp <- kappa2(data.frame(label,pred),"unweighted")
kappa <- getElement(kapp,"value")
print(kappa)  # output: 0.245283

w_kapp <- kappa2(data.frame(label,"equal")
weighted_kappa <- getElement(w_kapp,"value")
print(weighted_kappa)  # output: 0.443038

当我在 Python 中使用 kappa 计算 weighted_kappascript_python.py 时:

from sklearn.metrics import cohen_kappa_score

label = pd.read_csv(label_file,header=None).to_numpy()
pred = pd.read_csv(pred_file,header=None).to_numpy()
kappa = cohen_kappa_score(label.astype(int),pred.astype(int))
print(kappa)  # output: 0.24528301886792447
weighted_kappa = cohen_kappa_score(label.astype(int),pred.astype(int),weights='linear',labels=np.array(list(range(100))) )
print(weighted_kappa)  # output: 0.8359908883826879

我们可以发现kappaR计算的Python是一样的,但是weighted_kappa的{​​{1}}远低于{{来自 Rweighted_kappa 中的 1}}。哪个是错的?经过 2 天的研究,我发现 sklearn 中的 Python 包中的 weighted_kappa错误的。详情如下。

在调试过程中,我们会发现 irrR 中的混淆矩阵是:

enter image description here

我们可以发现顺序是错误的。标签的顺序应该从 irr 更改为 R,就像在 Python 中一样。似乎 [0,1,14,3,4,53,54,6] 包使用了基于字符串的排序方法而不是基于整数的排序方法,这会将 [0,6,54] 放在 irr 的前面。这个错误可以而且应该很容易纠正。

第二个错误:R 中的混淆矩阵不完整

在我的 143 中,这些值不能涵盖从 0 到 100 的所有可能值。因此 pred_test.csv 中的 label_test.csv 中的认混淆矩阵将错过那些未出现在数据中的值。这应该是固定的。

让我们看另一个例子。

irr 中,让我们将标签R 更改为 pred_test.csv。然后,我们再次运行 5499。结果是:

script_r.R

我们可以发现 script_python.py 中来自 In R: kappa: 0.245283 weighted_kappa: 0.443038 In Python: kappa: 0.24528301886792447 weighted_kappa: 0.592891760904685 weighted_kappa 根本没有变化。但是irrR的{​​{1}}从weighted_kappa减少到sklearn。所以我们知道Python又犯了一个错误

原因是0.83可以让我们将0.59传递给混淆矩阵,这样混淆矩阵的形状将是100 * 100,但是在irr中,混淆矩阵是根据 sklearnfull labels 的唯一值计算的,这会遗漏很多其他可能的值。这个错误会为这里的 irrlabel 分配相同的权重。因此最好在 pred 包中提供一个选项,让客户提供自定义 53,就像他们在 99 中从 irr 所做的那样。

解决方法

我已经给包的作者发了邮件,他说他会在下一次更新中修复这个错误。

详情如下:

实际上,我知道 kappa2 函数的这种尴尬行为。 这是由于因子水平的转换和重新排序。这些 实际上不是两个错误,而只是一个导致错误的错误 混淆矩阵的生成(您已经发现了)。你 可以通过删除 kappa2 函数中的第一行轻松修复它 (“收视率

一般来说,我的函数需要知道因子水平才能 正确计算 kappa。因此,对于您的数据,您需要存储 值作为具有适当可能因子水平的因子。 例如

label

评级

当您现在运行修改后的 kappa2-function(即没有第一个 行),结果应该是正确的。

kappa2(ratings) # 未加权 kappa2(ratings,"equal") # 加权 kappa 等权重

下次更新我的包时,我会考虑到这一点。

,

作者的解决方案是行不通的,因为在 kappa2 函数的 code 中,它将您的评分转换为矩阵,一旦将因子转换为矩阵,级别就会丢失,这是行:

ratings <- as.matrix(na.omit(ratings))

你可以在你的数据上试试,它被转换成一个字符:

lvl = 0:100
ratings = data.frame(label = factor(label[,1],levels=lvl),pred = factor(pred[,levels=lvl))

 as.matrix(ratings)
     label pred
[1,] "0"   "0" 
[2,] "1"   "1" 
[3,] "1"   "1" 
[4,] "1"   "0" 
[5,] "0"   "3" 
[6,] "14"  "4" 
[7,] "53"  "54"
[8,] "3"   "6" 

相同的结果:

kappa2(ratings,weight="equal")
 Cohen's Kappa for 2 Raters (Weights: equal)

 Subjects = 8 
   Raters = 2 
    Kappa = 0.368 

        z = 1.79 
  p-value = 0.0742 

我建议使用 DescTools,您只需要在 R 中使用 table() 函数提供混淆矩阵,并正确声明上述因素:

library(DescTools)

CohenKappa(table(ratings$label,ratings$pred),weight="Unweighted")
[1] 0.245283

CohenKappa(table(ratings$label,weight="Equal-Spacing")
[1] 0.8359909