簡體   English   中英

R中的`irr` package計算的加權Kappa錯了嗎?

[英]Is weighted Kappa calculated by `irr` package in R wrong?

我發現irr package 有 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

當我在script_python.py中使用Python計算kappaweighted_kappa時:

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

We can find that the kappa calculated by R and Python is the same, but the weighted_kappa from R is far lower than the weighted_kappa in sklearn from Python . 哪個是錯的? 經過2天的研究,我發現R中irr Rweighted_kappa是錯誤的。 詳情如下。

在調試過程中,我們會發現irr from R中的混淆矩陣為:

在此處輸入圖像描述

我們可以發現順序是錯誤的。 標簽的順序應從[0, 1, 14, 3, 4, 53, 54, 6]更改為[0, 1, 3, 4, 6, 14, 53, 54] ,就像在 Python 中一樣。 似乎irr package 使用了基於字符串的排序方法而不是基於整數的排序方法,這會將14放在3的前面。 這個錯誤可以而且應該很容易地糾正。

第二個錯誤:R 中的混淆矩陣不完整

在我的pred_test.csvlabel_test.csv中,這些值不能涵蓋從 0 到 100 的所有可能值。因此,來自R的默認混淆矩陣來自irr 這應該是固定的。

讓我們看另一個例子。

pred_test.csv中,讓我們將 label 從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

我們可以發現Rirrweighted_kappa完全沒有變化。 但是sklearnPythonweighted_kappa0.83減少到0.59 所以我們知道irr又犯了一個錯誤。

原因是sklearn可以讓我們將full labels傳遞給混淆矩陣,使得混淆矩陣的形狀為 100 * 100,但是在irr中,混淆矩陣的標簽是根據labelpred的唯一值計算的,其中會錯過很多其他可能的值。 這個錯誤會在這里為5399分配相同的權重。 所以最好在irr package 中提供一個選項,讓客戶提供客戶labels ,就像他們在sklearnPython中所做的那樣。

我已將 email 發送給 package 的作者,他說他將在下一次更新中修復該錯誤。

詳情如下:

實際上,我知道 kappa2 函數的這種尷尬行為。 這是由於因子水平的轉換和重新排序。 這些實際上不是兩個錯誤,而只是一個導致錯誤生成混淆矩陣(您已經發現)的錯誤。 您可以通過刪除 kappa2 函數中的第一行(“ratings <- as.matrix(na.omit(ratings))”)輕松修復它。 作為去除 NA 評級的一部分,這種轉換為數值是造成錯誤的原因。

一般來說,我的 function 需要知道因子水平才能正確計算 kappa。 因此,對於您的數據,您需要將值存儲為具有適當可能因子水平的因子。 例如

label <- c(0, 1, 1, 1, 0, 14, 53, 3) label <- 因子(標簽, 級別=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

對於我的 package 的下一次更新,我會考慮到這一點。

作者的解決方案不起作用,因為在 kappa2 function 的代碼中,它將您的評分轉換為矩陣,一旦您將因子轉換為矩陣,級別就會丟失,這是行:

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() function 提供混淆矩陣,並正確聲明上述因素:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM