【初心者向け】基礎&実践プログラミング

初心者がつまづきやすいところ、最短で実力が身につく方法をお伝えします。

【Python】カッパ(k)係数の計算

目的

  • コーエンの重み付きカッパ(k)係数(Cohen's kappa)をPythonで計算

scikit-learnのインストール

カッパ係数の計算には、scikit-learnを使うと簡単にできます。scikit-learnをインストールしていない場合は、以下のコマンドを実行してインストールしてください。

$ sudo pip3 install scikit-learn

データの準備

正解のラベル(クラス)を「y_true」の列に、AIの予測ラベルを「y_pred」の列に記載し、「label.csv」として保存。

label.csv

y_true y_pred
0 0
0 1
1 1
1 2
2 2
2 3
3 3
3 0
0 1

ソースコード

以下のコードを「calc_kappa.py」として保存。

cohen_kappa_scoreのところでカッパ係数を計算しています。また、引数にweights='quadratic'を渡してやることで、重み付きカッパ係数を計算することができます。kaggleでAIの精度を計測する際にはこちらが良く用いられる印象。

calc_kappa.py

# from sklearn.metrics import cohen_kappa_score
import pandas as pd
from sklearn.metrics import confusion_matrix, cohen_kappa_score

# load label
df = pd.read_csv("label.csv")
y_true = df["y_true"]
y_pred = df["y_pred"]

# check data using confusion matrix
print("#############Confusion Matrix#############")
conmat = confusion_matrix(y_true, y_pred)
print("RAW: y_true, COLUMN: y_label")
print(conmat)
print("##########################################\n")

# calc kappa statistic
k = cohen_kappa_score(y_true, y_pred, weights='quadratic')
print("Weighted Kappa k: {:.3f}".format(k))

実行

答えのラベルとAI予測のラベル情報が入った「label.csv」と重み付きカッパ係数を計算する「calc_kappa.py」を同じディレクトリの保存します。

$ ls
calc_kappa.py  label.csv

カッパ係数を計算するために、以下のコマンドを実行。最初に、正解と予測のラベルの混合行列(confusion matrix)が出てきます。次に、重み付きカッパ係数(Weighted Kappa k)が算出されます。

$ python3 calc_kappa.py 
#############Confusion Matrix#############
RAW: y_true, COLUMN: y_label
[[1 2 0 0]
 [0 1 1 0]
 [0 0 1 1]
 [1 0 0 1]]
##########################################

Weighted Kappa k: 0.418

結果の解釈

κ係数の目安としてよく使われるのはLandis and Kochによる基準。

0.0〜0.2: わずかに一致(slight agreement)

0.21〜0.40 まずまずの一致(fair agreement)

0.41〜0.60 中等度の一致(moderate agreement)

0.61〜0.80 かなりの一致(substantial agreement)

0.81〜1.0 ほぼ完全、完全一致(almost perfect or perfect agreement)

後に提案されたKrippendorffの基準は次の通り。

0.67未満 評価しない(discounted)

0.67〜0.80 不確かな結果(conclusions tentatively)

0.80以上 明確な結果(definite conclusions)

Neural Network Consoleを使っている場合

Neural Network Console(NNC)を使っている場合、出力として「output_result.csv」が出力される。

output_result.csv

x:image y:label y'__0 y'__1 y'__2 y'__3
D:\aaa\sub001.png 0 0.53138953 0.15399751 0.31428477 0.00032823457
D:\aaa\sub002.png 0 0.49342564 0.05760779 0.44819146 0.00077510934
D:\aaa\sub003.png 1 0.15003723 0.8461069 0.0038546587 1.3180296E-06
D:\aaa\sub004.png 2 0.49342564 0.05760779 0.44819146 0.00077510934
D:\aaa\sub005.png 1 0.53138953 0.15399751 0.31428477 0.00032823457

このoutput_result.csvから重み付きカッパ係数を計算するようにコードを更新した。
NNCをお使いの方は、以下のコード「calc_kappa_nnc.py」と「output_result.csv」を同じディレクトリにいれて実行してください。

calc_kappa_nnc.py

# from sklearn.metrics import cohen_kappa_score
import pandas as pd
from sklearn.metrics import confusion_matrix, cohen_kappa_score

# load label
filename = "output_result_PVH.csv"
print("Filename: {}".format(filename))
# filename = "output_result_DSWMH.csv"
df = pd.read_csv(filename)
# extract predicted label
y_pred = df.loc[:, df.columns.str.startswith("y'__")].idxmax(axis=1)
# change label name to number
for i in range(len(y_pred)):
    y_pred[i] = y_pred[i][-1]
y_pred = y_pred.astype("int64")  # change dtype from object to int64
# extract true label
y_true = df["y:label"]

# check data using confusion matrix
print("#############Confusion Matrix#############")
conmat = confusion_matrix(y_true, y_pred)
print("RAW: y_true, COLUMN: y_label")
print(conmat)
print("##########################################\n")

# calc kappa statistic
k = cohen_kappa_score(y_true, y_pred, weights='quadratic')
print("Weighted Kappa k: {:.3f}".format(k))