LoginSignup
20
9

More than 3 years have passed since last update.

[Python3] Fleiss' Kappa値を求める

Last updated at Posted at 2019-05-29

はじめに

複数人の評価の一致率を調べてみたかったのですが,評価者が2人か3人以上で求めるカッパ値が違う(2人のときはCohen's Kappaで3人以上のときはFleiss' Kappa)とのことでした.
調べてみるとCohen's Kappaについては沢山情報やプログラム,数式等があったのですが,Fleiss' Kappaについては「3人以上のときにはこっち使えよ」程度の文献しか引っかからず,英語じゃないと見つからなかった(ggり力不足かも?)ので日本語の情報として残したいというモチベーションで記事を書いています.

※とりあえず動かしたい人は下にプログラムがあります.

Fleiss' Kappa値の求め方

英語のwikipediaのページが例題つきでわかりやすかたので,英語アレルギーじゃない方はこちらを参照してください.

以下の式で計算できます.

\kappa=\frac{\bar{P}-\bar{P_e}}{1-\bar{P_e}}

ただし,

p_j = \frac{1}{Nn} \sum_{i=1}^{N} n_{ij} \\
\sum_{j=1}^{k} p_j = 1 \\
\bar{P} = \frac{1}{Nn(n-1)} \biggl(\sum_{i=1}^{N} \sum_{j=1}^{k} n_{ij}^2 - Nn \biggr) \\
\bar{P_e}= \frac{1}{N} \sum_{j=1}^{k} p_j^2

で,$n$は評価者の数,$N$は評価対象の数,$k$は評価対象への評価カテゴリーの数,$n_{ij}$はある$i$番目の評価対象にカテゴリー$j$を付与した人の数です.

(ここらへんの式はCohen's Kappaの話を見たほうがイメージがつかみやすいかもしれません)

kappa値の解釈

これも英語のwikipediaのページからそのまま持ってきました.

$\kappa$ 解釈
<0 一致していない
0.01 - 0.20 わずかに一致
0.21 - 0.40 だいたい一致
0.41 - 0.60 適度に一致
0.61 - 0.80 かなり一致
0.81 - 1.00 ほとんど一致

プログラム

入力値の例外処理とかはやっていないので,使う方は関数に投げる前に処理お願いします.

fleiss_kappa.py
# config:utf-8
'''
fleiss kappa値を計算するプログラム
'''

def compute_fleiss_kappa(rate_list: list, n: int) -> float:
    '''
    与えられた集計結果に対してのfleiss kappa値を返す関数

    Parameters
    ----------
    rate_list: list
      [size N * k: N = 評価対象の総数, k = 評価のカテゴリー数]
    n: int
      評価者の数

    Return
    ----------
    kappa: float
      fleiss kappa値
    '''
    N = len(rate_list)
    k = len(rate_list[0])
    # 入力された情報の確認
    print('評価者の数 = {}'.format(n))
    print('評価対象の数 = {}'.format(N))
    print('評価カテゴリー数 = {}'.format(k))

    # Piの値を求めて,P_barを求める
    P_bar = sum([(sum([el**2 for el in row]) - n) / (n * (n - 1)) for row in rate_list]) / N
    print('P_bar  = {}'.format(P_bar))

    # pjの値を求めて,Pe_barを求める
    Pe_bar = sum([(sum([row[j] for row in rate_list]) / (N * n)) ** 2 for j in range(k)])
    print('Pe_bar  = {}'.format(Pe_bar))

    # fleiss kappa値の計算
    kappa = float(0)
    try:
        kappa = (P_bar - Pe_bar) / (1 - Pe_bar)
    except ZeroDivisionError:
        kappa = float(1)

    return kappa

def main():
    n = 14
    test_list = [
      [0, 0, 0, 0, 14],
      [0, 2, 6, 4, 2],
      [0, 0, 3, 5, 6],
      [0, 3, 9, 2, 0],
      [2, 2, 8, 1, 1],
      [7, 7, 0, 0, 0],
      [3, 2, 6, 3, 0],
      [2, 5, 3, 2, 2],
      [6, 5, 2, 1, 0],
      [0, 2, 2, 3, 7]
    ]

    print('kappa = {}'.format(compute_fleiss_kappa(test_list, n)))

if __name__ == '__main__':
    main()

実行結果例

英語のwikipediaのページのworked exampleを実行した結果です.
評価者が14人いて,評価対象1(表の1行目)に対して5と評価した人が14人中14人といった見方になるかと思います.
2つめの評価対象には1を付けた人が0人,2が2人,3が6人,4が4人,5が2人です.

$ python3 fleiss_kappa.py
評価者の数 = 14
評価対象の数 = 10
評価カテゴリー数 = 5
P_bar  = 0.378021978021978
Pe_bar  = 0.21275510204081632
kappa = 0.20993070442195522

おわりに

もし何か間違いがあったり,わかりやすい文献をご存じの方はコメントお願い致しますm(_ _)m
(統計難しい...)

その他参考文献

各種一致係数

20
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
9