Расчет надежности между оценками

У меня есть следующий список списков:

[[1, 1, 1, 1, 3, 0, 0, 1],
 [1, 1, 1, 1, 3, 0, 0, 1],
 [1, 1, 1, 1, 2, 0, 0, 1],
 [1, 1, 0, 2, 3, 1, 0, 1]]

Где я хочу рассчитать оценку надежности между оценками. Есть несколько оценщиков (строк). Я не могу использовать каппа Флейса, так как строки не суммируются с одним и тем же числом. Каков хороший подход в этом случае?

3 ответа

Решение

Ответом на эту проблему было использование альфа-балла Криппендорфа:

Описание Википедии

Библиотека Python

import krippendorff

arr = [[1, 1, 1, 1, 3, 0, 0, 1],
       [1, 1, 1, 1, 3, 0, 0, 1],
       [1, 1, 1, 1, 2, 0, 0, 1],
       [1, 1, 0, 2, 3, 1, 0, 1]]    
res = krippendorff.alpha(arr)

Да, здесь важна подготовка данных. Давайте пройдем через это вместе.

Хотя альфа Криппендорфа может быть лучше по ряду причин, numpy и statsmodels предоставляют все необходимое для получения каппы Fleiss из вышеупомянутой таблицы. Каппа Флейсса более распространена в медицинских исследованиях, несмотря на то, что альфа Криппендорфа дает в основном тот же результат при правильном использовании . Если они дают существенно отличающиеся результаты, это может быть связано с рядом ошибок пользователя, наиболее важными из которых являются формат входных данных и уровень измерения (например, порядковый или номинальный) — пропустите решение (транспонирование и агрегирование): Каппа Флейсса 0,845

обратите особое внимание на то, какая ось представляет предмет, рейтинг или категорию!

Каппа Флейса

      statsmodels.stats import inter_rater as irr

В исходных данных рейтеры были строками, а темы — столбцами с целыми числами, представляющими назначенные категории (если я не ошибаюсь).

Я удалил одну строку, потому что было 4 строки и 4 категории, что может запутать ситуацию — теперь у нас 4 [0,1,2,3] категории и 3 строки.

      orig = [[1, 1, 1, 1, 3, 0, 0, 1],
        [1, 1, 1, 1, 3, 0, 0, 1],
        [1, 1, 1, 1, 2, 0, 0, 1]] 

Из документации функцииaggregate_raters ()

"конвертировать необработанные данные с формой (тема, рейтинг) в (тема, cat_counts) "

      irr.aggregate_raters(orig)

Это возвращает:

       (array([[2, 5, 0, 1],
        [2, 5, 0, 1],
        [2, 5, 1, 0]]),
array([0, 1, 2, 3]))

теперь... количество строк в исходном массиве равно количеству строк в первом из возвращенных массивов (3). Количество столбцов теперь равно количеству категорий ([0,1,2,3] -> 4). Содержимое каждой строки составляет в сумме 8, что равно количеству столбцов в исходных входных данных — при условии, что каждый оценщик оценил каждого субъекта. Это агрегирование показывает, как оценщики распределяются по категориям (столбцам) для каждого субъекта (строки). (Если бы согласие было совершенным по категории 2, мы бы увидели [0,0,8,0] или категорию 0 [8,0,0,0].

Функция ожидает, что строки будут субъектами. Посмотрите, как количество предметов не изменилось (3 ряда). И для каждого предмета подсчитывалось, сколько раз каждая категория была присвоена путем «просмотра», сколько раз категория (число) встречается в строке. Для первой строки или категории 0 присваивался дважды, 1 — пять раз, 2 — нет, 3 — один раз.

       [1, 1, 1, 1, 3, 0, 0, 1] -> [2, 5, 0, 1]

Второй массив возвращает значения категории. Если мы заменим обе тройки во входном массиве на девятки, распределение будет выглядеть так же, но последняя категория изменится.

      ori9 = [[1, 1, 1, 1, 9, 0, 0, 1],
        [1, 1, 1, 1, 9, 0, 0, 1],
        [1, 1, 1, 1, 2, 0, 0, 1]] 
       (array([[2, 5, 0, 1],
        [2, 5, 0, 1],
        [2, 5, 1, 0]]),
array([1, 2, ,3, 9]))      <- categories

агрегат_рейтеров() возвращает кортеж из ([данные], [категории])

В [data] строки остаются субъектами. агрегат_рейтеров() превращает столбцы из оценщиков в категории. Fleiss ожидает, что данные «таблицы» будут в следующем формате (тема, категория): https://en.wikipedia.org/wiki/Fleiss'_kappa#Data

Теперь к решению проблемы:

Что произойдет, если мы вставим исходные данные в Fleiss kappa: (мы просто используем данные «даты», а не список категорий «кошки»)

      dats, cats = irr.aggregate_raters(orig)
irr.fleiss_kappa(dats, method='fleiss')

-0,12811059907834096

Но почему? Что ж, взгляните на исходные данные — агрегат_рейтеров() предполагает, что рейтеры — это столбцы ! Это означает, что у нас есть полное несоответствие , например, между первой колонкой и предпоследней колонкой — Флейсс думает: «первая оценка всегда оценивается как «1», а предпоследняя всегда оценивается как «0» -> полное несоответствие по всем трем предметам.

Итак, что нам нужно сделать (извините, я нуб — возможно, не самый элегантный):

      giro = np.array(orig).transpose()
giro
       array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1],
       [1, 1, 1],
       [3, 3, 2],
       [0, 0, 0],
       [0, 0, 0],
       [1, 1, 1]]) 

Теперь у нас есть предметы в виде строк и оценщики в виде столбцов (три оценщика, назначающие 4 категории). Что произойдет, если мы вставим это в функциюaggregate_raters() и передадим полученные данные в fleiss? (используя индекс 0 для захвата первой части возвращаемого кортежа)

      irr.fleiss_kappa(irr.aggregate_raters(giro)[0], method='fleiss')

0,8451612903225807

Наконец… это имеет больше смысла, если все три оценщика полностью согласны друг с другом, за исключением предмета 5 [3, 3, 2].

альфа Криппендорфа

Текущая реализация криппендорфа ожидает данные в исходном формате с оценщиками в виде строк и столбцов в качестве субъектов — для подготовки данных не требуется функция агрегирования. Итак, я вижу, как это было более простым решением. Флейсс по-прежнему очень популярен в медицинских исследованиях, поэтому давайте посмотрим, как это можно сравнить:

      import krippendorff as kd
kd.alpha(orig)

0,9359

Вау… это намного выше, чем каппа Флейсса… Что ж, нам нужно сообщить Криппендорфу «уровень измерения Стивена для переменной». или вызываемый». – это для «разностной функции» альфы Криппендорфа. https://repository.upenn.edu/cgi/viewcontent.cgi?article=1043&amp;amp;context=asc_papers

      kd.alpha(orig, level_of_measurement='nominal')

0,8516

Надеюсь, это поможет, я многому научился, когда писал это.

Основная проблема здесь в том, что вы не правильно применили данные, которые вы дали. Смотрите здесь для правильной организации. У вас есть четыре категории (оценки 0-3) и восемь предметов. Таким образом, ваша таблица должна иметь восемь строк и четыре столбца, независимо от количества рецензентов. Например, верхняя строка - это список оценок, присвоенных первому элементу:

[0, 4, 0, 0]   ... since everyone rated it a `1`.

Твой -inf значение делится на 0 при оценке P[j] для предпоследнего столбца.


Мой предыдущий ответ, нормализующий баллы, был основан на моем неправильном истолковании Флейса; Я имел в виду другую надежность. Есть много способов вычислить такую ​​метрику; один из них - согласованность относительных рейтинговых баллов (которые можно получить при нормализации); другой - преобразовать строку каждого оценщика в график относительного ранжирования и вычислить сходство между этими графиками.

Обратите внимание, что Fleiss не совсем подходит для рейтинговой ситуации с относительной метрикой: предполагается, что это задача классификации, а не ранжирования. Fleiss не чувствителен к тому, насколько далеко друг от друга находятся рейтинги; он знает только то, что рейтинги отличались: спаривание (0,1) столь же разрушительно, как и спаривание (0,3).

Другие вопросы по тегам