Ao final deste artigo você vai saber de onde o viés vem, calcular métricas de fairness por grupo com poucas linhas de Python, entender por que não dá para satisfazer todas ao mesmo tempo e escolher uma correção compatível com o seu caso e com a LGPD.
O problema real
Uma financeira treina um modelo de crédito com dez anos de aprovações e rejeições. No teste, a acurácia é alta. Meses depois, uma análise por grupo mostra que pessoas de um determinado grupo são rejeitadas bem mais do que outras com renda e histórico parecidos. O algoritmo não "decidiu" discriminar. Ele aprendeu a reproduzir o padrão dos dados, e os dados refletiam decisões humanas do passado.
Viés, aqui, é um padrão sistemático de erro ou de resultado que favorece ou prejudica um grupo. Um exemplo isolado não prova nada. A pergunta útil é sempre estatística: o que acontece com cada grupo, em média?
De onde o viés vem
- Amostragem: um grupo aparece pouco nos dados, e o modelo erra mais nele. Reconhecimento facial treinado majoritariamente com um tipo de rosto é o caso clássico.
- Rótulo: o que você chama de "verdade" já embute julgamentos. Se o rótulo é "foi contratado" e as contratações passadas foram enviesadas, o modelo aprende o viés como se fosse critério.
- Histórico: o mundo era desigual e os dados guardam isso, mesmo quando rótulos e amostras estão tecnicamente corretos.
- Proxy: você remove a coluna sensível, mas CEP, escola ou sobrenome continuam correlacionados com ela. Retirar o atributo do modelo não retira o viés.
- Agregação: um único modelo para populações que se comportam de forma diferente funciona bem para a maioria e mal para as minorias.
- Medição: a métrica escolhida pode esconder o problema. Acurácia global alta convive com acurácia baixa em um subgrupo.
Como medir: sempre por grupo
O primeiro passo é calcular as métricas separadamente para cada grupo. Precisa de três colunas: o resultado real (y_true), a decisão do modelo (y_pred) e o atributo do grupo, que pode ser usado só para auditoria e não como entrada do modelo.
import numpy as np
import pandas as pd
def metricas_por_grupo(y_true, y_pred, grupo) -> pd.DataFrame:
df = pd.DataFrame({"y": y_true, "p": y_pred, "g": grupo})
linhas = []
for g, d in df.groupby("g"):
positivos = d[d.y == 1] # quem deveria ser aprovado
aprovados = d[d.p == 1] # quem o modelo aprovou
linhas.append({
"grupo": g,
"n": len(d),
"acuracia": (d.y == d.p).mean(),
"taxa_aprovacao": d.p.mean(),
"recall": positivos.p.mean() if len(positivos) else np.nan,
"precisao": aprovados.y.mean() if len(aprovados) else np.nan,
})
return pd.DataFrame(linhas).set_index("grupo")
tabela = metricas_por_grupo(y_true, y_pred, grupo)
print(tabela.round(2))
Cada coluna responde a uma pergunta diferente, e cada uma corresponde a uma definição de justiça:
- Paridade demográfica: a taxa de aprovação deve ser parecida entre grupos. Mede-se com a razão entre a menor e a maior taxa. Uma regra prática vem do direito do trabalho dos EUA, a "regra dos quatro quintos": razão abaixo de 0,8 é sinal de alerta. É uma heurística de triagem, não um padrão legal brasileiro.
- Igualdade de oportunidade: entre quem merecia aprovação, a chance de ser aprovado deve ser parecida. Compara o recall entre grupos.
- Paridade preditiva: entre os aprovados, a proporção que de fato deu certo deve ser parecida. Compara a precisão.
Calcule também o intervalo de confiança quando um grupo tiver poucas dezenas de exemplos. Uma diferença de 8 pontos em 40 pessoas pode ser só ruído. Bibliotecas como Fairlearn e AIF360 trazem essas métricas prontas, com intervalos e gráficos, e valem a pena em projetos reais.
As métricas conflitam
Quando a proporção de casos positivos reais difere entre grupos (as "taxas-base"), é matematicamente impossível satisfazer ao mesmo tempo paridade preditiva e igualdade de oportunidade, exceto num modelo perfeito. Esse resultado aparece em trabalhos de Chouldechova (2017) e Kleinberg et al. (2016) e é o motivo de não existir "o modelo justo" universal. Você escolhe a definição que combina com o dano que quer evitar.
- Crédito: o dano principal é negar a quem pagaria. Igualdade de oportunidade (mesmo recall) costuma ser o foco.
- Triagem de currículos: se há risco de excluir um grupo na entrada do funil, olhe taxa de aprovação por grupo, e investigue as causas antes de forçar paridade.
- Diagnóstico médico: erros dos dois tipos custam caro, então compare falsos negativos e falsos positivos por grupo, e a calibração das probabilidades.
Documente a escolha e o motivo. Quem revisar o modelo no futuro precisa saber por que aquela métrica foi a prioridade.
Como corrigir
Corrija a causa primeiro, a métrica depois. Em ordem de preferência:
- Melhorar os dados. Coletar mais exemplos do grupo sub-representado, revisar rótulos suspeitos, avaliar se o rótulo mede o que você pensa. É lento, mas ataca a origem.
- Reponderar. Dar mais peso aos exemplos de grupos raros no treino evita duplicar dados.
from sklearn.linear_model import LogisticRegression
freq = pd.Series(grupo).value_counts(normalize=True)
pesos = pd.Series(grupo).map(1 / freq).to_numpy()
pesos = pesos / pesos.mean() # mantém a escala média em 1
modelo = LogisticRegression(max_iter=1000)
modelo.fit(X_treino, y_treino, sample_weight=pesos)
- Rebalancear por reamostragem. Funciona, mas duplicar poucos exemplos faz o modelo decorá-los.
- Treinar com restrição de fairness. O Fairlearn, por exemplo, tem redutores que otimizam a acurácia sob uma restrição de paridade escolhida.
- Ajustar limiares por grupo no pós-processamento. Reduz a diferença de recall, mas trata pessoas de grupos distintos de forma diferente. Antes de adotar, consulte o jurídico: dependendo do contexto, pode ser considerado tratamento discriminatório.
Evite remédios que mexem em decisões individuais de forma aleatória para "equilibrar" números. Eles não corrigem a causa e criam outro problema de justiça.
Depois de corrigir, meça de novo, e meça também a acurácia geral. Existe custo, mas ele costuma ser menor do que se imagina, e quase sempre menor que o custo de um processo ou de uma crise de reputação.
E nos LLMs?
Modelos de linguagem herdam o viés dos textos de treino e se manifestam como estereótipos em respostas, diferenças de qualidade entre dialetos e idiomas e variação de decisão quando só o nome ou o gênero muda no pedido. O teste mais simples é o de pares contrastivos: rode o mesmo prompt trocando só o atributo (por exemplo, o nome em um currículo) e compare as respostas em uma amostra grande. Inclua esses pares no seu conjunto de evals e monitore em produção com observabilidade.
LGPD e decisão automatizada
A LGPD (Lei 13.709/2018) traz, no art. 6º, o princípio da não discriminação: o tratamento não pode ter fins discriminatórios ilícitos ou abusivos. O art. 20 garante ao titular o direito de solicitar a revisão de decisões tomadas unicamente com base em tratamento automatizado que afetem seus interesses, incluindo decisões de perfil de crédito, e de receber informações claras sobre os critérios usados. A lei não exige, no texto atual, que essa revisão seja feita por uma pessoa natural, mas a ANPD pode orientar sobre o tema. Na prática, tenha um canal de contestação, explicações compreensíveis e documentação das métricas por grupo. Em dúvida, procure assessoria jurídica.
Dados sensíveis, como origem racial ou étnica, têm hipóteses legais restritas de tratamento (art. 11). Medir viés exige o atributo, então defina com o jurídico como coletá-lo para auditoria, com finalidade clara e acesso limitado.
Armadilhas comuns
- Olhar só a acurácia geral. Ela mascara diferenças entre grupos.
- Acreditar que remover a coluna sensível resolve. Os proxies continuam lá.
- Forçar paridade demográfica quando as taxas-base diferem por motivos legítimos. Você acaba errando mais, e de forma que prejudica quem queria proteger.
- Tomar a correlação como causa. Investigue o mecanismo antes de decidir a correção.
- Medir uma vez e esquecer. O mundo muda, e o viés pode aparecer depois do deploy.
Quando a correção agressiva não compensa
Se o grupo tem poucos exemplos, a diferença medida pode ser ruído e a correção piora o modelo. Se a diferença nas taxas reflete uma diferença real e legítima que não é discriminatória, forçar paridade pode ser pior. Nesses casos, registre a análise, colete mais dados e acompanhe. A comparação com outras técnicas de ajuste está em RAG, fine-tuning ou prompt.
Para treinar o olhar, jogue Detetive de Viés. Quer aplicar isso na sua empresa? Marque uma conversa de 45 minutos em https://iauaicloud.com.br/consultoria