Utilizando Python para Mitigar Discriminação em Modelos de Machine Learning

Kleyton Costa
Data Hackers
Published in
6 min readJun 18, 2023

Um tutorial básico para mitigar vieses e discriminação em modelos de machine learning utilizando as bibliotecas HolisticAI e Sklearn

Porque Devemos Mitigar Vieses e Discriminação

Modelos de machine learning podemos ser usados em aplicações críticas, como em processos seletivos, no sistema judicial, na avaliação de crédito bancário ou em sistemas de reconhecimento facial. Nesses casos, é especialmente importante garantir que os algoritmos não discriminem e tratem todos igualmente.

O documentário Coded Bias, de 2020, retrata diversos casos em que modelso de machine learning apresentam comportamentos tendenciosos. Quando esse comportamento tendencioso resulta em desvantagens para um indivíduo ou grupo de indivíduos, dizemos que o algoritmo apresenta um viés (ou bias).

Vamos pegar o exemplo de um algoritmo de reconhecimento facial. Se nossos dados de treinamento forem compostos principalmente por sujeitos do sexo masculino, nosso algoritmo não será capaz de classificar corretamente mulheres e grupos minoritários. Isso é um exemplo de um algoritmo tendencioso.

De acordo com um estudo realizado em 2018, três sistemas populares de reconhecimento facial pareciam estar tendenciosos e classificavam incorretamente até 34,7% das mulheres negras contra 0,8% de erro para o caso de homens brancos.

Em 2020, outro estudo analisou sistemas de reconhecimento facial de diferentes empresas. Os resultados mostram que os modelos possuem uma acuária elevada (mais de 90%), porém esta acurácia não é homogênea, apresentando um claro viés de discriminação racial. A acurácia para pessoas de pele escura chegou a ser até 1/3 menor do que para pessoas de pele clara.

Inequity in face recognition algorithms

Viés no Contexto de Responsible AI

Com a massificação das tecnologias de inteligência artificial a área de Responsible AI ganha uma importância ainda maior. É crucial que empresas/pesquisadores/indivíduos que fazem uso ou constroem modelos de inteligência artificial tenham responsabilidade no desenvolvimento desses sistemas. O primeiro passo é entendermos o que é um viés.

O viés pode ser entendido de diferentes maneiras. Em geral, quando falamos de vieses em modelos de machine learning estamos nos referindo a incapacidade que o modelo possui para capturar a complexidade dos dados, ou seja, um modelo que erra suas previsões sistematicamente. Nesse caso, um modelo que tenha um viés alto tem a característica underfitting.

No contexto de Fairness e Responsible AI, definimos viés como um preconceito indesejado nas decisões tomadas por um sistema de IA e que são sistematicamente desvantajosas para uma pessoa ou grupo. Existem vários tipos de vieses e eles podem ser introduzidos inadvertidamente em algoritmos em qualquer estágio do processo de desenvolvimento, seja durante a geração de dados ou a construção do modelo.

Para podermos medir se um sistema trata diferentes grupos de maneira igualitária, devemos concordar com as seguintes definições de igualdade:

  • Igualdade de Resultados: Se selecionarmos esta definição, assumimos que todos os subgrupos devem ter resultados iguais. Por exemplo, em um contexto de recrutamento, podemos exigir que a porcentagem de candidatos contratados seja consistente entre os grupos (por exemplo, queremos contratar 5% de todas as candidatas mulheres e 5% de todos os candidatos homens).
  • Igualdade de Oportunidades: Se selecionarmos esta definição, assumimos que todos os subgrupos devem ter igualdade de oportunidades. Por exemplo, se tivermos um algoritmo de reconhecimento facial, podemos querer que o classificador tenha um desempenho igualmente bom para todas as etnias, gêneros, etc.

Neste link você pode conhecer diferentes métricas para igualdade de resultados e iguladade de oportunidades!

Holistic AI Pipeline + Sklearn

Através da biblioteca holisticai podemos aplicar dezenas de estratégias de mitigação e mensuração de vieses para modelos de machine learning para tarefas de classificação, regressão, agrupamento ou sistemas de recomendação.

Neste tutorial de apresentação trataremos de um caso específico: mitigação de vieses em uma tarefa de classificação utilizando a estratégia Exponentiated Gradient Reduction.

Passo 1: leitura dos dados e pré-processamento

Neste exemplo vamos utilizar o Adult Dataset. Começamos realizando a leitura dos dados e um pré-processamento simplificado para obtermos dois grupos de interesse a partir do sexo: femino e masculino. Assim, poderemos investigar e se necessário mitigar o viés existente entre os dois grupos.

# carregar os dados
from holisticai.datasets import load_adult
from sklearn.model_selection import train_test_split
import pandas as pd

# leitura dos dados
data = load_adult()
df = pd.concat([data["data"], data["target"]], axis=1)
protected_variables = ["sex", "race"]
output_variable = ["class"]

# pré-processamento simplificado
y = df[output_variable].replace({">50K": 1, "<=50K": 0})
X = pd.get_dummies(df.drop(protected_variables + output_variable, axis=1))

# separar o grupo_a = feminino e o grupo_b = masculino
group = ["sex"]
group_a = df[group] == "Female"
group_b = df[group] == "Male"
data_ = [X, y, group_a, group_b]

# separação dos dados em conjunto de treino e teste
dataset = train_test_split(*data_, test_size=0.2, shuffle=True)
train_data = dataset[::2]
test_data = dataset[1::2]

Passo 2: análise exploratória dos dados

from holisticai.bias.plots import group_pie_plot
from holisticai.bias.plots import histogram_plot

fig, axs = plt.subplots(nrows = 1, ncols = 2, figsize = (15,5))

# separar os atributos "sex" e "class"
p_attr_sex = df['sex']
p_attr_class = df['class']

# gráfico circular para o atributo "sex"
group_pie_plot(p_attr_sex, ax = axs[0])

# gráfico circular para o atributo "class"
group_pie_plot(p_attr_class, ax = axs[1])
# histrograma por "race" e marcardo por "class"
histogram_plot(df['race'], df['class'])

As figuras indicam claramente que o conjunto de dados é desequilibrado, com uma representação significativamente maior de homens e indivíduos pertencentes a variável “race” branca. Isso pode levar a resultados tendenciosos e minar a capacidade de generalização de quaisquer descobertas ou modelos treinados com esses dados.

Passo 3: treinar o modelo baseline

# configurar o Pipeline
pipeline = Pipeline(steps=[
('scaler', StandardScaler()),
('classifier', LogisticRegression()),
])

# treinar o modelo no Pipeline
X_train, y_train, group_a, group_b = train_data
pipeline.fit(X_train, y_train)

# testar o modelo no Pipeline
X_test, y_test, group_a, group_b = test_data
y_pred = pipeline.predict(X_test)

# gerar métricas de igualdade de resultados e igualdade de oportunidades
metrics_baseline = classification_bias_metrics(group_a, group_b, y_pred, y_test, metric_type='both')

Passo 4: treinar um modelo com mitigador de viés

# importar a estratégia de mitigação
from holisticai.bias.mitigation import ExponentiatedGradientReduction

# selecionar o modelo de classificação
model = LogisticRegression()

# selecionar a estratégia de mitigação in-processing
inprocessing_model = ExponentiatedGradientReduction(
constraints="DemographicParity",
verbose=1
).transform_estimator(model)

# configurar o Pipeline
pipeline = Pipeline(
steps=[
('scalar', StandardScaler()),
("bm_inprocessing", inprocessing_model),
]
)

# treinar o modelo com mitigador no Pipeline
X_train, y_train, group_a, group_b = train_data
fit_params = {
"bm__group_a": group_a,
"bm__group_b": group_b
}

pipeline.fit(X_train, y_train, **fit_params)

# testar o modelo com mitigador no Pipeline
X_test, y_test, group_a, group_b = test_data
predict_params = {
"bm__group_a": group_a,
"bm__group_b": group_b,
}
y_pred = pipeline.predict(X_test, **predict_params)

# gerar métricas para igualdade de resultados e igualdade de oportunidades
metrics_mitigated = classification_bias_metrics(group_a, group_b, y_pred, y_test, metric_type='both')

Passo 5: comparar os resultados

results = pd.concat([metrics_baseline['Value'], metrics_mitigated[['Value', 'Reference']]], axis = 1)
results.columns = ['Baseline', 'Com Mitigador', 'Valor de Referência']
results

A coluna “Referência” mostra quais são os valores que cada métrica considera como justo. Por exemplo, Disparate Impact igual a 1 mostra que os resultados são justos, não possuem vieses. Sem o mitigador (Baseline) o resultado da métrica é 0.2772, distante do que seria justo. Aplicando o mitigador esse valor passa a ser 0.8743, ou seja, resultados justos!

O resultado comparativo mostra que a estratégia de mitigação foi eficaz para mitigar os vieses existentes entre os grupos A (feminino) e B (masculino).

Referências

O código completo está disponível neste link e aberto para sugestões e comentários.

Dúvidas e sugestões? Entre em contato no LinkedIn ou no email kleyton.vsc@gmail.com

--

--

Kleyton Costa
Data Hackers

Researcher at @holisticai | kleytondacosta.com | Machine Learning Scientist | en-pt