16  ✏️ Esercizi

(esercizi-irr)=

In questo tutorial vedremo come calcolare l’affidabilità tra giudici. Il metodo per calcolare l’affidabilità tra giudici dipende dal tipo di dati (categoriali, ordinali, continui) e dal numero di giudici.

source("../../code/_common.R")
suppressPackageStartupMessages({
    library("irr")
    library("lme4")
})

16.1 Dati categoriali

Iniziamo con dati categoriali e utilizziamo un sottoinsieme dei dati forniti dal data frame diagnoses del pacchetto irr.

data(diagnoses)
glimpse(diagnoses)
Rows: 30
Columns: 6
$ rater1 <fct> 4. Neurosis, 2. Personality Disorder, 2. Personality Disorder, ~
$ rater2 <fct> 4. Neurosis, 2. Personality Disorder, 3. Schizophrenia, 5. Othe~
$ rater3 <fct> 4. Neurosis, 2. Personality Disorder, 3. Schizophrenia, 5. Othe~
$ rater4 <fct> 4. Neurosis, 5. Other, 3. Schizophrenia, 5. Other, 4. Neurosis,~
$ rater5 <fct> 4. Neurosis, 5. Other, 3. Schizophrenia, 5. Other, 4. Neurosis,~
$ rater6 <fct> 4. Neurosis, 5. Other, 5. Other, 5. Other, 4. Neurosis, 3. Schi~
dat <- diagnoses[, 1:3]
head(dat)
A data.frame: 6 x 3
rater1 rater2 rater3
<fct> <fct> <fct>
1 4. Neurosis 4. Neurosis 4. Neurosis
2 2. Personality Disorder 2. Personality Disorder 2. Personality Disorder
3 2. Personality Disorder 3. Schizophrenia 3. Schizophrenia
4 5. Other 5. Other 5. Other
5 2. Personality Disorder 2. Personality Disorder 2. Personality Disorder
6 1. Depression 1. Depression 3. Schizophrenia

Iniziamo considerando il caso di due giudici. Per questi dati calcoleremo il Kappa di Cohen.

kappa2(dat[, c(1, 2)], "unweighted")
 Cohen's Kappa for 2 Raters (Weights: unweighted)

 Subjects = 30 
   Raters = 2 
    Kappa = 0.651 

        z = 7 
  p-value = 2.63e-12 

Il Kappa di Cohen valuta la concordanza tra due valutatori su una scala categoriale. Può essere usato quando i valutatori assegnano categorie, non punteggi numerici, agli oggetti di interesse. Un valore di Kappa maggiore di 0 indica una maggiore concordanza tra i valutatori rispetto a quella che ci si aspetterebbe per caso, mentre un valore di 0 indica che la concordanza non è maggiore di quella casuale.

Nel caso presente, l’output indica che:

  • Subjects = 30: Ci sono 30 oggetti o soggetti che sono stati valutati dai giudici.
  • Raters = 2: Due valutatori hanno partecipato alla valutazione.
  • Kappa = 0.651: Il valore di Kappa, 0.651, suggerisce una concordanza sostanziale tra i due valutatori. Secondo le linee guida generalmente accettate per l’interpretazione del coefficiente di Kappa, un valore tra 0.61 e 0.80 indica una concordanza sostanziale.

L’output fornisce anche un test statistico per valutare se la concordanza osservata è significativamente maggiore di quella che ci si aspetterebbe per caso:

  • z = 7: Il valore z del test statistico è 7. Questo indica la distanza della statistica di test (Kappa osservato) dal valore di Kappa atteso sotto l’ipotesi nulla (nessuna concordanza oltre il caso), misurata in unità di deviazione standard. Un valore elevato indica una forte evidenza contro l’ipotesi nulla.
  • p-value = 2.63e-12: Il p-value è estremamente basso, molto inferiore a qualsiasi soglia di significatività comune (ad esempio, 0.05 o 0.01). Questo suggerisce che la probabilità di osservare un valore di Kappa come quello ottenuto (o più estremo) se in realtà non ci fosse concordanza tra i valutatori (oltre quella casuale) è estremamente bassa. In altre parole, c’è una forte evidenza statistica che la concordanza tra i due valutatori è significativamente maggiore di quella che ci si aspetterebbe per caso.

In sintesi, l’output indica una concordanza sostanziale tra i due valutatori sulla scala categorica utilizzata, e questa concordanza è statisticamente significativa. Questo suggerisce che i giudizi dei due valutatori sono affidabili e consistenti tra loro oltre quello che ci si aspetterebbe semplicemente per caso.

Se ci sono più di due giudici, usiamo il Kappa di Fleiss.

kappam.fleiss(dat)
 Fleiss' Kappa for m Raters

 Subjects = 30 
   Raters = 3 
    Kappa = 0.534 

        z = 9.89 
  p-value = 0 

È anche possibile utilizzare il Kappa esatto di Conger (1980).

kappam.fleiss(dat, exact = TRUE)
 Fleiss' Kappa for m Raters (exact value)

 Subjects = 30 
   Raters = 3 
    Kappa = 0.55 

Nel caso di 3 giudici, otteniamo un valore di Kappa di Fleiss pari a 0.53, il che indica un’accordo moderato tra gli osservatori. Questo significa che c’è una certa concordanza tra di loro, ma non c’è né una forte né una perfetta corrispondenza. In generale, un Kappa di Fleiss compreso tra 0.41 e 0.60 può essere considerato come un’accordo moderato.

16.2 Dati ordinali

Se i dati sono ordinali, è necessario utilizzare un Kappa ponderato. Ad esempio, se i valori possibili sono basso, medio e alto, allora se un caso viene valutato come medio da un codificatore e alto dall’altro, essi sarebbero in un accordo maggiore rispetto a una situazione in cui le valutazioni fossero basso e alto.

Per chiarire ulteriormente, il concetto di Kappa ponderato si basa sull’idea che non tutte le discrepanze tra i codificatori siano ugualmente gravi. Nell’esempio dato, la differenza tra le valutazioni medio e alto è considerata meno significativa rispetto alla differenza tra basso e alto, perché le categorie sono vicine l’una all’altra nell’ordine. Il Kappa ponderato introduce quindi dei pesi per riflettere questa differenza di gravità nelle discrepanze, valutando le discrepanze minori (come tra medio e alto) meno severamente delle discrepanze maggiori (come tra basso e alto). Questo approccio è particolarmente utile in contesti dove l’ordine e la distanza tra le categorie sono informativi e importanti per l’analisi.

Usiamo i dati forniti dal data frame anxiety del pacchetto irr.

data(anxiety)

dfa <- anxiety[, c(1, 2)]
dfa
A data.frame: 20 x 2
rater1 rater2
<int> <int>
1 3 3
2 3 6
3 3 4
4 4 6
5 5 2
6 5 4
7 2 2
8 3 4
9 5 3
10 2 3
11 2 2
12 6 3
13 1 3
14 5 3
15 2 2
16 2 2
17 1 1
18 2 3
19 4 3
20 3 4

Possiamo calcolare il Kappa ponderato sui giudizi di due valutatori. È possibile usare pesi lineari o quadrati delle differenze.

kappa2(dfa, "squared")
 Cohen's Kappa for 2 Raters (Weights: squared)

 Subjects = 20 
   Raters = 2 
    Kappa = 0.297 

        z = 1.34 
  p-value = 0.18 

Questo valore di Kappa suggerisce che c’è un livello di accordo “equo” tra i due valutatori, considerando che i pesi delle discrepanze tra le valutazioni sono calcolati al quadrato. La scala convenzionale per interpretare Kappa è la seguente: valori ≤ 0 indicano nessun accordo, 0.01–0.20 leggero, 0.21–0.40 equo, 0.41–0.60 moderato, 0.61–0.80 sostanziale, e 0.81–1.00 quasi perfetto.

Il valore di z è una misura della distanza statistica del valore di Kappa dal valore nullo (nessun accordo oltre il caso), espresso in termini di deviazioni standard. Un p-value di 0.18 indica che non c’è una significatività statistica per rifiutare l’ipotesi nulla di nessun accordo oltre il caso, al livello di significatività convenzionale di 0.05.

kappa2(dfa, "equal")
 Cohen's Kappa for 2 Raters (Weights: equal)

 Subjects = 20 
   Raters = 2 
    Kappa = 0.189 

        z = 1.42 
  p-value = 0.157 

Con pesi uguali per le discrepanze tra le valutazioni, il valore di Kappa scende a 0.189, indicando sempre un livello di accordo “leggero” verso “equo” tra i valutatori. Questo suggerisce che l’accordo non è molto forte e che le valutazioni differiscono più di quanto non facciano con i pesi al quadrato.

Con un valore di z leggermente più alto rispetto al primo caso e un p-value di 0.157, anche qui non c’è evidenza statistica sufficiente per rifiutare l’ipotesi nulla. Il risultato implica che l’accordo osservato potrebbe ancora essere dovuto al caso, anche se il p-value è leggermente più basso qui, suggerendo una tendenza (anche se non significativa) verso un accordo maggiore rispetto al caso.

In conclusione, entrambi gli output indicano un livello di accordo che va da leggero a equo tra i due valutatori, con nessuna delle due misure che raggiunge la significatività statistica. Ciò suggerisce che, mentre c’è qualche grado di accordo oltre la coincidenza casuale, non è forte. La scelta dei pesi influisce leggermente sui risultati, con i pesi al quadrato che mostrano un livello di accordo leggermente superiore rispetto ai pesi uguali. Questo potrebbe riflettere la natura delle discrepanze nelle valutazioni: l’utilizzo di pesi al quadrato penalizza di più le grandi discrepanze rispetto ai pesi uguali.

kappa2(dfa, "unweighted")
 Cohen's Kappa for 2 Raters (Weights: unweighted)

 Subjects = 20 
   Raters = 2 
    Kappa = 0.119 

        z = 1.16 
  p-value = 0.245 
  • Kappa = 0.119: Questo valore rappresenta il livello più basso di accordo tra i tre casi analizzati, indicando un accordo molto debole tra i valutatori. La mancanza di pesi implica che tutti i disaccordi sono stati trattati uniformemente, indipendentemente dalla loro gravità o distanza.
  • z = 1.16, p-value = 0.245: Questo risultato conferma ulteriormente che l’accordo tra i valutatori non è statisticamente significativo, con un p-value ancora più alto rispetto ai casi precedenti, suggerendo una forte possibilità che qualsiasi accordo osservato sia casuale.

I diversi valori di Kappa nei tre scenari riflettono l’effetto della ponderazione (o mancanza di essa) sulla valutazione dell’accordo. L’accordo sembra diminuire man mano che si passa da pesi quadrati a pesi uguali e infine a nessuna ponderazione, indicando che la severità dei disaccordi ha un impatto notevole sull’accordo percepito.

Nessuno dei tre scenari ha mostrato un accordo statisticamente significativo tra i valutatori, come indicato dai p-value superiori a 0.05. Ciò suggerisce che, indipendentemente dal metodo di ponderazione utilizzato, l’accordo osservato tra i valutatori potrebbe non essere distintamente migliore di quello che ci si aspetterebbe per caso.

La scelta del metodo di ponderazione può influenzare fortemente la stima dell’accordo tra i valutatori. In contesti dove la gravità dei disaccordi è importante, i pesi possono fornire una misura più accurata dell’accordo effettivo. Tuttavia, la mancanza di significatività statistica in tutti e tre i casi solleva questioni sulla coerenza delle valutazioni o sulla possibile necessità di formazione aggiuntiva per i valutatori per migliorare l’affidabilità delle loro valutazioni.

I dati usati in precedenza erano numerici, ma il Kappa ponderato può anche essere calcolato nel caso di dati categoriali. In R i dati categoriali sono codificati in termini di fattori. Si noti che i livelli dei fattori devono essere nell’ordine corretto, altrimenti i risultati saranno errati.

dfa2 <- dfa
dfa2$rater1 <- factor(dfa2$rater1, levels = 1:6, labels = LETTERS[1:6])
dfa2$rater2 <- factor(dfa2$rater2, levels = 1:6, labels = LETTERS[1:6])
dfa2 |> head()
A data.frame: 6 x 2
rater1 rater2
<fct> <fct>
1 C C
2 C F
3 C D
4 D F
5 E B
6 E D
levels(dfa2$rater1) |> print()
[1] "A" "B" "C" "D" "E" "F"
levels(dfa2$rater2) |> print()
[1] "A" "B" "C" "D" "E" "F"

I risultati sono uguali a quelli ottenuti con i dati numerici.

kappa2(dfa2, "squared")
 Cohen's Kappa for 2 Raters (Weights: squared)

 Subjects = 20 
   Raters = 2 
    Kappa = 0.297 

        z = 1.34 
  p-value = 0.18 
kappa2(dfa2, "equal")
 Cohen's Kappa for 2 Raters (Weights: equal)

 Subjects = 20 
   Raters = 2 
    Kappa = 0.189 

        z = 1.42 
  p-value = 0.157 

16.3 Dati continui

Quando ci si confronta con variabili continue, è necessario calcolare il Coefficiente di Correlazione Intraclasse (ICC) per valutare l’accordo tra le misurazioni. La selezione dell’ICC appropriato richiede l’attenzione su diversi aspetti (Shrout e Fleiss, 1979). Questi includono:

  1. Selezione del Modello: È cruciale determinare se trattare esclusivamente i soggetti come effetti casuali, seguendo il modello “oneway” (impostazione predefinita), oppure se sia soggetti che valutatori sono stati scelti casualmente da un pool più ampio, adottando il modello “twoway”. Tale decisione dipende dalla struttura del disegno di studio e dall’obiettivo dell’analisi.

  2. Interesse per le Differenze: Nel caso in cui si desideri esaminare le differenze nei punteggi medi tra i valutatori, è preferibile calcolare l’“accordo” anziché la “coerenza” (quest’ultima è l’opzione predefinita). Questa scelta è cruciale quando le differenze sistematiche tra i valutatori sono rilevanti per l’analisi.

  3. Unità di Analisi: È necessario decidere se l’unità di analisi dovrebbe essere la media di più punteggi o se mantenere l’analisi su valori singoli (impostazione predefinita, unità=“singola”). La trasformazione dell’unità di analisi in “media” può essere appropriata quando l’interesse è concentrato sulla stima aggregata delle misurazioni, mentre l’opzione “singola” è generalmente preferita per esaminare la variabilità tra misurazioni individuali.

La scelta tra queste opzioni dovrebbe essere guidata dagli obiettivi specifici della ricerca, dalla natura dei dati e dal contesto in cui le misurazioni sono state raccolte. Tali decisioni influenzano notevolmente l’interpretazione del Coefficiente di Correlazione Intraclasse e, di conseguenza, le conclusioni che possono essere tratte riguardo all’accordo o alla variabilità delle misurazioni all’interno del campione studiato.

Per illustrare questi concetti, useremo il set di dati anxiety dal pacchetto “irr”.

data(anxiety)
anxiety |> head()
A data.frame: 6 x 3
rater1 rater2 rater3
<int> <int> <int>
1 3 3 2
2 3 6 1
3 3 4 4
4 4 6 4
5 5 2 3
6 5 4 2
icc(anxiety, model = "twoway", type = "agreement")
 Single Score Intraclass Correlation

   Model: twoway 
   Type : agreement 

   Subjects = 20 
     Raters = 3 
   ICC(A,1) = 0.198

 F-Test, H0: r0 = 0 ; H1: r0 > 0 
 F(19,39.7) = 1.83 , p = 0.0543 

 95%-Confidence Interval for ICC Population Values:
  -0.039 < ICC < 0.494

Possiamo replicare questo risultato usando un modello ad effetti misti. Per fare questo dobbiamo prima trasformare i dati in formato long.

anxiety_long <- anxiety %>%
    mutate(subject = row_number()) %>%
    pivot_longer(
        cols = starts_with("rater"),
        names_to = "rater",
        values_to = "score",
        names_prefix = "rater"
    )
glimpse(anxiety_long)
Rows: 60
Columns: 3
$ subject <int> 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7,~
$ rater   <chr> "1", "2", "3", "1", "2", "3", "1", "2", "3", "1", "2", "3", "1~
$ score   <int> 3, 3, 2, 3, 6, 1, 3, 4, 4, 4, 6, 4, 5, 2, 3, 5, 4, 2, 2, 2, 1,~

Possiamo ora adattare il modello misto ai dati.

model <- lmer(score ~ 1 + (1 | subject) + (1 | rater), data = anxiety_long)

Il procedimento utilizzato da lmer per modellare i dati e calcolare componenti di varianza, che poi possono essere utilizzati per stimare l’Intraclass Correlation Coefficient (ICC), si basa sull’analisi degli effetti misti. Ecco una spiegazione dettagliata del processo:

  1. Definizione del Modello: lmer(score ~ 1 + (1 | subject) + (1 | rater), data = anxiety_long) specifica un modello lineare misto, dove score è la variabile dipendente. La notazione (1 | subject) indica che si vuole considerare un effetto casuale per ogni soggetto (subject) che corrisponde unicamente all’intercetta. Analogamente, (1 | rater) indica un effetto casuale, corrispondente all’intercetta, per ogni valutatore (rater), permettendo che ogni valutatore possa avere una sua propria tendenza generale nella valutazione. Il termine 1 rappresenta l’intercetta fissa comune a tutti i dati.

  2. Effetti Fissi e Casuali: In questo modello, l’unico effetto fisso è l’intercetta globale (il termine 1 nel modello), che rappresenta la media generale dei punteggi di ansia. Gli effetti casuali sono rappresentati dalle varianze associate a ciascun soggetto e valutatore, indicando che si riconosce la presenza di variazioni individuali nei punteggi di ansia attribuibili a questi due fattori.

  3. Interpretazione delle Componenti di Varianza: Le componenti di varianza estratte dal modello rappresentano la quantità di variazione nei punteggi di ansia attribuibili a variazioni tra soggetti (var_subject), a variazioni tra valutatori (var_rater), e alla variazione residua non spiegata dal modello (var_residual).

Dopo aver stimato le componenti di varianza, l’ICC può essere calcolato come una proporzione della varianza tra soggetti e tra giudici rispetto alla varianza totale.

Esaminiamo le componenti di varianza:

vc <- as.data.frame(VarCorr(model))
vc
A data.frame: 3 x 5
grp var1 var2 vcov sdcor
<chr> <chr> <chr> <dbl> <dbl>
subject (Intercept) NA 0.3991227 0.6317616
rater (Intercept) NA 0.1684205 0.4103906
Residual NA NA 1.4482458 1.2034308

Calcolo dell’ICC:

(vc$vcov[1] + vc$vcov[2]) / (vc$vcov[1] + vc$vcov[2] + vc$vcov[3])
0.281548906954477

Questo risultato riproduce quello trovato da icc():

performance::icc(model)
A icc: 1 x 3
ICC_adjusted ICC_conditional ICC_unadjusted
<dbl> <dbl> <dbl>
0.2815489 0.2815489 0.2815489