Skip to contents

ac_qual_reliability() calcula métricas de concordância entre a classificação feita pela LLM e uma classificação humana de referência, com intervalos de confiança via bootstrap.

É a última porta antes de publicar um estudo de análise de conteúdo assistida por LLM. Nenhuma referência metodológica atual (Krippendorff, 2018; Gwet, 2014; Gilardi et al., 2023) aceita rotulagem automática sem um subconjunto codificado por humano e concordância documentada.

Quatro métricas são computadas por padrão, cada uma respondendo a uma pergunta diferente:

  • Percent agreement (percent_agreement): fração de documentos em que LLM e humano concordam. Fácil de reportar, mas ignora concordância por acaso: infla para categorias binárias com distribuição desigual.

  • Alpha de Krippendorff (krippendorff): padrão-ouro em análise de conteúdo. Corrige por acaso, aceita missings, funciona com qualquer número de categorias. Krippendorff (2018, sec. 12.4) recomenda alfa >= 0,800 para conclusões sem ressalvas e 0,667 <= alfa < 0,800 apenas para conclusões provisórias; abaixo de 0,667 os dados não devem sustentar conclusões.

  • AC1 de Gwet (gwet_ac1): alternativa mais estável quando as categorias são muito desbalanceadas (o "paradoxo do kappa" de Feinstein & Cicchetti, 1990: kappa despenca mesmo com alta concordância observada se uma categoria domina). Gwet (2014) propõe o AC1 justamente para esse caso.

  • F1 macro (f1_macro): média não ponderada dos F1 por categoria (Sokolova & Lapalme, 2009). Útil quando você quer garantir que a LLM está indo bem também nas categorias raras, não só nas frequentes. Não é corrigido por acaso, então não deve ser lido com as faixas de Landis & Koch (1977), que foram propostas para o kappa.

Como a coluna interpretation é preenchida

Cada métrica usa a referência própria dela, para não misturar escalas:

  • Alpha de Krippendorff: >= 0,800 confiável; 0,667-0,800 só conclusões provisórias; < 0,667 insuficiente (Krippendorff, 2018).

  • AC1 de Gwet: faixas de Landis & Koch (1977): < 0 pobre; 0-0,20 leve; 0,21-0,40 razoável; 0,41-0,60 moderada; 0,61-0,80 substancial; 0,81-1 quase perfeita. Gwet (2014, cap. 6) usa essas faixas como referência de benchmarking.

  • Percent agreement: >= 0,90 alta; 0,80-0,90 aceitável na maioria dos casos; 0,70-0,80 só em estudos exploratórios; < 0,70 insuficiente (Neuendorf, 2017; Lombard, Snyder-Duch & Bracken, 2002).

  • F1 macro: não há faixa canônica na literatura; o valor é reportado sem rótulo qualitativo.

Essas faixas são convenções, não testes estatísticos: o próprio Landis & Koch (1977, p. 165) as chamam de arbitrárias. Por isso o IC bootstrap importa: um alfa de 0,82 com IC de 0,61 a 0,95 não permite afirmar que a confiabilidade passa de 0,800 (Krippendorff, 2018, sec. 12.5, decide justamente pela probabilidade de o alfa ficar abaixo do mínimo exigido).

Intervalos de confiança de 95% vêm de bootstrap não paramétrico (padrão: 1000 réplicas). Reporte pelo menos Krippendorff e F1 macro no artigo, com os ICs; discuta divergências humano × LLM em amostra de casos representativos.

Usage

ac_qual_reliability(
  llm,
  human,
  cat_col = "categoria",
  metrics = c("krippendorff", "gwet_ac1", "f1_macro", "percent_agreement"),
  bootstrap = 1000L,
  ci_level = 0.95,
  by_variable = FALSE,
  exclude_status = c("estouro_contexto", "limite_taxa", "timeout", "erro_servidor",
    "parcial"),
  ...
)

Arguments

llm

Tibble com classificação LLM, saída de ac_qual_code().

human

Tibble com classificação humana, saída de ac_qual_import_human().

cat_col

Nome da coluna de categoria. Padrão: "categoria".

metrics

Vetor de métricas a calcular. Padrão: c("krippendorff", "gwet_ac1", "f1_macro", "percent_agreement").

bootstrap

Número de amostras bootstrap para IC. Padrão: 1000.

ci_level

Nível de confiança do IC. Padrão: 0.95.

by_variable

Lógico. Se TRUE, calcula também métricas binárias (concordância, precisão, recall, F1, Gwet AC1, alfa de Krippendorff) para cada categoria do codebook individualmente, tratando a presença de cada categoria como um problema sim/não: essencial quando multilabel = TRUE, onde um único categoria ("a|b") mistura várias decisões binárias independentes que as métricas agregadas (acima) não conseguem diagnosticar separadamente. Denominadores zero (ex.: uma categoria nunca escolhida por nenhum dos dois lados) geram NA, nunca 0 ou 1 artificiais. Padrão FALSE.

exclude_status

Vetor de valores da coluna status (ver ac_qual_code()) a excluir da comparação antes de calcular as métricas por variável: documentos que falharam na classificação não têm uma categoria confiável para comparar. Ignorado se llm não tiver coluna status. Padrão: c("estouro_contexto", "limite_taxa", "timeout", "erro_servidor", "parcial").

...

Ignorado.

Value

Tibble com colunas: metric, estimate, ci_lower, ci_upper, interpretation. Quando by_variable = TRUE, o resultado carrega também um atributo by_variable: um tibble com uma linha por categoria do codebook e colunas categoria, n, vp, fp, fn, vn, concordância, precisao, recall, f1, gwet_ac1, krippendorff_alfa.

References

Krippendorff, K. (2018). Content Analysis: An Introduction to Its Methodology (4th ed.). SAGE.

Gwet, K. L. (2014). Handbook of Inter-Rater Reliability (4th ed.). Advanced Analytics.

Landis, J. R.; Koch, G. G. (1977). The Measurement of Observer Agreement for Categorical Data. Biometrics, 33(1), 159-174.

Feinstein, A. R.; Cicchetti, D. V. (1990). High agreement but low kappa: I. The problems of two paradoxes. Journal of Clinical Epidemiology, 43(6), 543-549.

Lombard, M.; Snyder-Duch, J.; Bracken, C. C. (2002). Content analysis in mass communication: Assessment and reporting of intercoder reliability. Human Communication Research, 28(4), 587-604.

Neuendorf, K. A. (2017). The Content Analysis Guidebook (2nd ed.). SAGE.

Sokolova, M.; Lapalme, G. (2009). A systematic analysis of performance measures for classification tasks. Information Processing & Management, 45(4), 427-437.

Examples

# Simular saidas: LLM (coded) e revisao humana (humano_df)
# ambos com as colunas doc_id + categoria
coded <- tibble::tibble(
  doc_id    = paste0("d", 1:5),
  categoria = c("favor", "contra", "favor", "contra", "favor")
)
humano_df <- tibble::tibble(
  doc_id    = paste0("d", 1:5),
  categoria = c("favor", "contra", "contra", "contra", "favor")
)

# Calcular métricas de confiabilidade (bootstrap curto so para demonstrar;
# em uso real, deixe o padrao de 1000 replicas)
rel <- ac_qual_reliability(
  llm       = coded,
  human     = humano_df,
  bootstrap = 50
)
#> Calculando confiabilidade em 5 documentos comuns...
#> ℹ Interpretação: alfa por Krippendorff (2018); AC1 por Landis & Koch (1977) e
#>   Gwet (2014); percentual por Neuendorf (2017); F1 sem rótulo.
#> ℹ IC 95% via bootstrap (n = 50).
print(rel)
#> # A tibble: 4 × 5
#>   metric             estimate ci_lower ci_upper interpretation                  
#>   <chr>                 <dbl>    <dbl>    <dbl> <chr>                           
#> 1 percent_agreement      0.8     0.445        1 aceitável na maioria dos casos …
#> 2 krippendorff_alpha     0.64   -0.125        1 insuficiente (< 0,667; Krippend…
#> 3 gwet_ac1               0.6     0.231        1 substancial (Landis & Koch, 197…
#> 4 f1_macro               0.8     0.306        1 sem faixa canônica (não corrigi…