按R中的“irr”包计算的加权Kappa是否错误?

2024-09-29 02:27:22 发布

您现在位置:Python中文网/ 问答频道 /正文

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

请告诉我这两个bug是否真的存在,或者我误解了什么。

您可以使用以下示例复制这些bug

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

我有两对疾病程度的分数(从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计算kappaweighted_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

我们可以发现由{}和{}计算出的{}是相同的,但是来自{}的{}远低于来自{}的{}中的{}。哪一个是错的?经过两天的研究,我发现R中的irr包中的weighted_kappa是错误的。详情如下

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

enter image description here

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

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

在我的pred_test.csvlabel_test.csv中,值不能覆盖从0到100的所有可能值。因此,来自Rirr中的默认混淆矩阵将丢失数据中未出现的值。这应该是固定的

让我们看另一个例子

pred_test.csv中,让我们将标签从54更改为99。然后,我们再次运行script_r.Rscript_python.py。结果是:

In R:
kappa: 0.245283
weighted_kappa: 0.443038

In Python:
kappa: 0.24528301886792447
weighted_kappa: 0.592891760904685

我们可以发现R中的irr中的weighted_kappa没有任何变化。但是{}中{}的{}从{}减少到{}。所以我们知道irr又犯了一个错误

原因是sklearn可以让我们将full labels传递给混淆矩阵,这样混淆矩阵的形状将是100*100,但是在irr中,混淆矩阵的标签是从labelpred的唯一值计算出来的,这将丢失许多其他可能的值。此错误将在此处为5399分配相同的权重。因此,最好在irr包中提供一个选项,让custumer提供custumlabels,就像他们在sklearnfrom Python中所做的那样


Tags: csvtestread错误script矩阵标签label
2条回答

我已经给该软件包的作者发了电子邮件,他说他将在下一次更新中修复该漏洞

详情如下:

Actually, I am aware of this awkward behavior of the kappa2-function. This is due to the conversion and reordering of factor levels. These are actually not two bugs but only one that results in an incorrect generation of the confusion matrix (which you already found out). You can easily fix it by deleting the first row in the kappa2-function ("ratings <- as.matrix(na.omit(ratings))"). This conversion to numerical value as part of the removal of NA ratings is responsible for the error.

In general, my function needs to know the factor levels in order to correctly compute kappa. Thus, for your data, you would need to store the values as factors with the appropriate possible factor levels. E.g.

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 <- factor(pred, levels=0:100)

ratings <- data.frame(label,pred)

When you now run the modified kappa2-function (i.e. without the first line), the results should be correct.

kappa2(ratings) # unweighted kappa2(ratings, "equal") # weighted kappa with equal weights

For the next update of my package, I will take this into account.

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

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,您只需要使用R中的table()函数提供混淆矩阵,并正确声明上述因子:

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

相关问题 更多 >