1

我发现irr包有 2 个用于计算weighted kappa.

请告诉我这两个错误是否真的存在,或者我误解了一些东西。

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

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

我有 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,pred),"equal")
weighted_kappa <- getElement(w_kapp,"value")
print(weighted_kappa)  # output: 0.443038

当我Python用来计算kappaandweighted_kappa时,在script_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

我们可以发现,kappa计算的 byRPython是相同的,但是weighted_kappafromR远低于weighted_kappain sklearnfrom Python。哪个是错的?经过2天的研究,我发现weighted_kappafrom irrpackage inR是错误的。详情如下。

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

在此处输入图像描述

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

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

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

让我们看另一个例子。

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_kappafrom irrinR完全没有变化。但是weighted_kappasklearninPython减少到0.83to 0.59。所以我们知道irr又犯了一个错误。

原因是sklearn可以让我们将 传递full labels给混淆矩阵,使混淆矩阵的形状为 100 * 100,但是在 中irr,混淆矩阵的标签是根据 和 的唯一值计算的labelpred这会错过很多其他的可能的值。53这个错误会给和这里分配相同的权重99。所以最好在irrpackage 中提供一个选项,让客户提供他们在fromlabels中所做的那样的客户。sklearnPython

4

2 回答 2

0

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

详情如下:

实际上,我知道 kappa2 函数的这种尴尬行为。这是由于因子水平的转换和重新排序。这些实际上不是两个错误,而只是一个导致错误生成混淆矩阵(您已经发现)的错误。您可以通过删除 kappa2 函数中的第一行(“ratings <- as.matrix(na.omit(ratings))”)轻松修复它。作为去除 NA 评级的一部分,这种转换为数值是造成错误的原因。

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

label <- c(0, 1, 1, 1, 0, 14, 53, 3) label <- factor(label, levels=0:100) pred <- c(0, 1, 1, 0, 3, 4 , 54, 6) pred <- 因子(pred, 水平=0:100)

评分 <- data.frame(label,pred)

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

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

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

于 2021-05-14T08:33:12.857 回答
0

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

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

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

lvl = 0:100
ratings = data.frame(label = factor(label[,1],levels=lvl),
                     pred = factor(pred[,1],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,您只需要使用table()R 中的函数提供混淆矩阵,并按照上述正确声明的因素:

library(DescTools)

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

CohenKappa(table(ratings$label,ratings$pred), weight="Equal-Spacing")
[1] 0.8359909
于 2021-05-14T09:48:42.957 回答