【问题标题】:Inter-rater reliability calculation for multi-raters data多评估者数据的评估者间可靠性计算
【发布时间】:2019-10-22 04:32:37
【问题描述】:

我有以下列表:

[[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]]

在我想计算inter-rater 可靠性分数的地方,有多个评分者(行)。我不能使用 Fleiss 的 kappa,因为这些行的总和不是相同的数字。在这种情况下有什么好的方法?

【问题讨论】:

    标签: python statistics statsmodels


    【解决方案1】:

    这里的基本问题是您没有正确应用所提供的数据。有关适当的组织,请参阅here。您有四个类别(评分 0-3)和八个科目。因此,无论审阅者的数量如何,您的表格都必须有 8 行和 4 列。例如,第一行是对第一项的评分:

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

    您的-inf 值来自倒数第二列的 P[j] 分数除以 0。


    我早先的答案是标准化分数,是基于我的对 Fleiss 的误解;我想到了不同的可靠性。 有很多方法可以计算这样的度量;一是相对评分点的一致性(您可以通过标准化获得);另一种是将每个评分者的行转换为相对排名图,并计算这些图之间的相似度。

    请注意,Fleiss 完全适用于具有相对度量的rating 情况:它假定这是一项分类任务,而不是排名。 Fleiss 对评级相差多远并不敏感。它只知道评级不同:(0,1)配对与(0,3)配对一样具有破坏性。

    【讨论】:

    • 通过 statsmodels.stats.inter_rater.fleiss_kappa 运行这个得到 -inf 的分数,你知道出了什么问题吗?
    • 是的——你仍然需要预处理你的数据。我只给了你一个微不足道的缩放比例;你仍然需要处理那个零评级的情况:当j=6 时,你的 P[j] 的分母是 0.00。
    【解决方案2】:

    这个问题的一个答案是使用 krippendorff alpha score:

    Wikipedia Description

    Python Library

    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)
    

    【讨论】:

    • 我有类似的情况,想确保我理解您的数据表示正确。这里每一行代表一个评分者分数,对吧?例如,第一行 [1, 1, 1, 1, 3, 0, 0, 1] 代表第一个评分者。
    • 那是我的确切情况是的。所以解决方案对你的情况也应该有效!
    【解决方案3】:

    是的,数据准备是关键。一起来看看吧。

    虽然 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

    希望这会有所帮助,我在写这篇文章时学到了很多东西。

    【讨论】:

      猜你喜欢
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      • 2010-09-21
      • 1970-01-01
      相关资源
      最近更新 更多