ktrのブログ

だいたい体験談と勉強したことのアウトプット

Kappa係数のメモ

Kappa係数

Kaggle Courseraの評価指標のセクションでKappa係数が出てきました。
検索しても中々情報が出てきませんが、最近だとQuadratic Weighted KappaがPetFinder.my Adoption Prediction | Kaggle で評価指標になっています。
一見すると統計検定2級くらいの知識っぽいですが、勉強した記憶がなかったのでメモ的にまとめてみました

*あくまでもメモです

定義

\displaystyle{
\kappa = \frac{P_{o}-P_{c}}{1-P_{c}}
}
  •  P_{o}:一致率
  •  P_{c}:偶然の一致率

カッパ係数 kappa coefficient ある現象を2人の観察者が観察した場合の結果がどの程度一致しているかを表す統計量。カッパ統計量や一致率とも言う。0から1までの値をとり、値が大きいほど一致度が高いといえる。カッパ係数 | 統計用語集 | 統計WEB

計算手順

ある二人の医師(A, B)が患者の病気の診断を行うとする。患者40人をそれぞれが診断した結果は以下になった

A\BNOYES
NO20424
YES41216
2416

医師Aと医師BのNOでの一致患者が20人でYESでの一致患者が12人という想定です

単純な一致率はYESとNOが一致した割合で対角成分から以下のように求めることができます

\displaystyle{
p_{o} = \frac{20+12}{40} = 0.80
}


次にAとBの診断がたまたま一致するような期待度を求める。
例えばYESで考えるとAは16/40でYESと診断し、Bも16/40でYESと診断するので

\displaystyle{
yes = \frac{16}{40} \times \frac{16}{40} \times 40 = 6.4 人
}

くらいの人数が一致するであろうと考えられる。同様にして他も計算すると

A\BNOYES
NO14.49.624
YES9.66.416
2416

よって偶然の一致率は

\displaystyle{
p_{c} = \frac{14.4+6.6}{40} = 0.52
}

Kappa係数の定義より

\displaystyle{
\kappa = \frac{P_{o}-P_{c}}{1-P_{c}} = \frac{0.80-0.52}{1-0.52} = 0.58
}

となる。

つまりKappa係数とは偶然一致することが期待される分を除いた残りがどれくらいの割合で一致したかを計算した値であるといえそうです

Pythonで計算

cohen_kappa_scoreメソッドを使えば計算できます。
confusion_matrixで集計表と同じ結果がでることも確認しておきます。

import numpy as np
from sklearn.metrics import confusion_matrix, cohen_kappa_score

A = np.array([0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1])
B = np.array([0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1])


confusion_matrix(A, B)
'''output
array([[20,  4],
       [ 4, 12]])
'''

cohen_kappa_score(A, B)
'''output
0.5833333333333333
'''

重み付きkappa係数

例として患者の状態を良いを0として0(良),1(普通),2(悪)のように多段階評価している場合を考えます

  • Aが患者に0(良)の評価を与えて、Bが患者に1(普通)の評価を与えたとき
  • Aが患者に0(良)の評価を与えて、Bが患者に2(悪)の評価を与えたとき

を全く同じ一致として考えることは正しいと思えません。
つまり遠い一致になったときはペナルティーを与えて調整する必要があります。

例として以下の集計表を考えます

A\B013
055111
1410317
351612
14161040

偶然の一致も2x2と同様に計算します

A\B013
03.854.42.7511
15.956.84.2517
34.24.8312
14161040

重みの考慮はいろいろあるようですが、scikit-learnの実装では以下のように計算されています。

\displaystyle{
w_{i, j} = (i - j)^{2}
}

i, jはセルの位置

2乗で重みをとったのでQuadratic Weighted Kappaと呼ばれるそうです。そして一般的に重み付きといったらQuadratic Weighted Kappaを指すようです。

A\B013
0014
1101
3410

この重みとそれぞれのマトリックスの要素の積をとり、以下のように計算します

\displaystyle{
\kappa=1-\frac{\sum_{i=1}^{k} \sum_{j=1}^{k} w_{i j} x_{i j}}{\sum_{i=1}^{k} \sum_{j=1}^{k} w_{i j} m_{i j}}
}

xは実際の一致で、mが偶然の一致

Pythonでの計算

cohen_kappa_scoreweights='quadratic'と指定すれば簡単に計算できます。

A = array([1, 1, 1, 1, 0, 0, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 0, 0, 2, 0, 0,
       2, 2, 2, 1, 0, 2, 0, 1, 2, 1, 0, 1, 2, 2, 1, 0, 1, 0])
B = array([1, 1, 1, 1, 0, 0, 2, 0, 1, 2, 0, 1, 1, 2, 2, 2, 2, 1, 1, 0, 0, 1,
       2, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 0, 2, 1, 2, 1, 1])
       
confusion_matrix(A, B)

'''output
array([[ 5,  5,  1],
       [ 4, 10,  3],
       [ 5,  1,  6]])
'''

cohen_kappa_score(A, B, weights='quadratic')

'''output
0.21610169491525433
'''

2x2の場合は対角線上の要素でKappa係数を計算しているので直感的で分かりやすいです。

重み付きKappa係数の場合は対角成分を0にして一致していない要素で不一致率を出して、1から引くことで一致率としているイメージでしょうか?

いろいろ調べましたが、よく分かりませんでした。 詳しい方がいたらコメント等で指摘いただけると勉強になります。おわり。