![](/img/trans.png)
[英]How can I specify a loss function to be quadratic weighted kappa in Keras?
[英]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
計算kappa
和weighted_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
R
的weighted_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.csv
和label_test.csv
中,這些值不能涵蓋從 0 到 100 的所有可能值。因此,來自R
的默認混淆矩陣來自irr
這應該是固定的。
讓我們看另一個例子。
在pred_test.csv
中,讓我們將 label 從54
更改為99
。 然后,我們再次運行script_r.R
和script_python.py
。 結果是:
In R:
kappa: 0.245283
weighted_kappa: 0.443038
In Python:
kappa: 0.24528301886792447
weighted_kappa: 0.592891760904685
我們可以發現R
中irr
的weighted_kappa
完全沒有變化。 但是sklearn
中Python
的weighted_kappa
從0.83
減少到0.59
。 所以我們知道irr
又犯了一個錯誤。
原因是sklearn
可以讓我們將full labels
傳遞給混淆矩陣,使得混淆矩陣的形狀為 100 * 100,但是在irr
中,混淆矩陣的標簽是根據label
和pred
的唯一值計算的,其中會錯過很多其他可能的值。 這個錯誤會在這里為53
和99
分配相同的權重。 所以最好在irr
package 中提供一個選項,讓客戶提供客戶labels
,就像他們在sklearn
的Python
中所做的那樣。
我已將 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.