是的,数据准备是关键。一起来看看吧。
虽然 Krippendorff 的 alpha 可能出于多种原因而优越,但 numpy 和 statsmodels 提供了从上述表格中获取 Fleiss kappa 所需的一切。 Fleiss 的 kappa 在医学研究中更为普遍,尽管 Krippendorff alpha 提供了几乎相同的结果如果使用正确。如果他们提供了截然不同的结果,这可能是由于许多用户错误,最重要的是输入数据的格式和测量级别(例如,序数与标称) - 跳过解决方案(转置& 合计):Fleiss kappa 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() 函数的文档
"将形状为 (subject, rater) 的原始数据转换为 (subject, cat_counts)"
irr.aggregate_raters(orig)
这会返回:
(array([[2, 5, 0, 1],
[2, 5, 0, 1],
[2, 5, 1, 0]]),
array([0, 1, 2, 3]))
现在... orig 数组中的行数等于第一个返回数组中的行数 (3)。列数现在等于类别数([0,1,2,3] -> 4)。每行的内容加起来为 8,这等于 orig 输入数据中的列数——假设每个评估者都对每个主题进行了评分。此聚合显示评估者如何分布在每个主题(行)的类别(列)中。 (如果在类别 2 上的协议是完美的,我们将看到 [0,0,8,0];或类别 0 [8,0,0,0]。
该函数期望行是主题。看看主题的数量如何没有改变(3 行)。对于每个主题,它通过“查看”在行中找到多少次类别(数字)来计算每个类别被分配的次数。对于第一行或类别,0 被分配了两次,1 次被分配了 5 次,2 没有被分配,3 被分配了一次
[1, 1, 1, 1, 3, 0, 0, 1] -> [2, 5, 0, 1]
第二个数组返回类别值。如果我们将输入数组中的两个 3 都替换为 9,则分布看起来相同,但最后一个类别发生了变化。
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
aggregate_raters() 返回一个由 ([data], [categories]) 组成的元组
在 [data] 中,行保持主题。 aggregate_raters() 将评分者的列转换为类别。 Fleiss 期望“表格”数据采用以下(主题、类别)格式:https://en.wikipedia.org/wiki/Fleiss'_kappa#Data
现在解决问题:
如果我们将原始数据插入 Fleiss kappa 会发生什么:
(我们只使用数据“dats”而不是类别列表“cats”)
dats, cats = irr.aggregate_raters(orig)
irr.fleiss_kappa(dats, method='fleiss')
-0.12811059907834096
但是……为什么?好吧,看看 orig 数据 - aggregate_raters() 假设 raters 作为列 !这意味着我们有完全分歧,例如在第一列和倒数第二列之间——Fleiss 认为:“排名第一的人总是评为“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] 之外所有三个评估者都完全同意。
克里彭多夫的阿尔法
当前的 krippendorff 实现需要 orig 格式的数据,其中评估者作为行,列作为主题——不需要聚合函数来准备数据。所以我可以看到这是一个更简单的解决方案。 Fleiss 在医学研究中仍然非常流行,所以让我们看看它的比较:
import krippendorff as kd
kd.alpha(orig)
0.9359
哇……这比 Fleiss 的 kappa 高很多……好吧,我们需要告诉 Krippendorff “Steven 对变量的测量水平。它必须是“名义”、“有序”、“ interval'、'ratio' 或可调用对象。” - 这是用于 Krippendorff alpha 的“差分函数”。 https://repository.upenn.edu/cgi/viewcontent.cgi?article=1043&context=asc_papers
kd.alpha(orig, level_of_measurement='nominal')
0.8516
希望这会有所帮助,我在写这篇文章时学到了很多东西。