Responsible AI is crucial for developers of AI models and enterprise customers. Responsible AI plays an important role in model development, training, fine-tuning, evaluation, and deployment to ensure that AI models are safe, stable, fair, and socially ethical. Data Science Workshop (DSW) of Alibaba Cloud Platform for AI (PAI) allows you to integrate Responsible AI tools to perform fairness analysis, error analysis, and interpretability analysis on generated AI models.
How it works
Fairness analysis ensures that the output of models are unbiased and are not influenced by unreasonable factors. The following section describes the core principles of fairness analysis:
Avoiding bias: Identify and reduce bias in data and algorithms to ensure that AI systems do not make unfair decisions based on personal characteristics, such as gender, race, or age.
Representative data: Train AI models together with representative datasets to ensure that the models accurately represent and serve all user groups without marginalizing minority groups.
Transparency and explainability: Increase the transparency of AI systems and allow end-users and decision-makers to understand the AI decision-making processes and outputs by using explainable AI technologies.
Continuous monitoring and assessment: Regularly monitor and assess AI systems to identify and correct unfair biases or decisions that may arise.
Diversity and inclusion: Incorporate the concepts of diversity and inclusion in the design and development of AI systems to ensure that issues are considered from multiple backgrounds and perspectives, including the diversity of the team composition.
Compliance and ethical principles: Adhere to relevant laws, regulations, and ethical standards, including respect for human rights to ensure that AI applications do not cause harm or injustice.
This topic describes how to use the responsible-ai-toolbox to perform fairness analysis on the model in DSW. In this topic, the fairness of a model that predicts whether the annual income exceeds 50K is evaluated in terms of gender and race.
Prepare the environment and resources
DSW instance: If you do not have a DSW instance, create a DSW instance. For more information, see Create a DSW instance. We recommend that you use the following configurations:
Instance type: ecs.gn6v-c8g1.2xlarge
Image: Python3.9 or later. In this topic, the official image used is tensorflow-pytorch-develop:2.14-pytorch2.1-gpu-py311-cu118-ubuntu22.04.
Model: responsible-ai-toolbox supports regression and binary classification models based on Sklearn, PyTorch, and TensorFlow frameworks.
Training dataset: We recommend that you use your dataset. If you want to use a sample dataset, see the "Step 3. Prepare the datasets" section of this topic.
Algorithm model: We recommend that you use your algorithm model. If you want to use a sample algorithm model, see the "Step 5: Train the model" section of this topic.
Step 1: Go to the DSW Gallery
Log on to the PAI console.
In the upper-left corner, select a region based on your business requirements.
In the left-side navigation pane, choose QuickStart > Notebook Gallery. Search for Responsible AI fairness and click Open in DSW.
Select an AI workspace and DSW instance and click Open Notebook. The system opens the Responsible AI-fairness analysis notebook.
Step 2: Import the dependency package
Install the responsible-ai-toolbox dependency package (raiwidgets) for subsequent evaluation.
!pip install raiwidgets==0.34.1
Step 3: Prepare the dataset
In this example, the OpenML dataset 1590 is used. You can directly run the following script to load the OpenML 1590 dataset.
from raiutils.common.retries import retry_function
from sklearn.datasets import fetch_openml
class FetchOpenml(object):
def __init__(self):
pass
# Obtain the OpenML dataset whose data ID is 1590 .
def fetch(self):
return fetch_openml(data_id=1590, as_frame=True)
fetcher = FetchOpenml()
action_name = "Dataset download"
err_msg = "Failed to download openml dataset"
max_retries = 5
retry_delay = 60
data = retry_function(fetcher.fetch, action_name, err_msg,
max_retries=max_retries,
retry_delay=retry_delay)
You can also load your own dataset. The following section provides sample commands for datasets in the CSV format.
import pandas as pd
# Load your dataset in the CSV format.
# Use pandas to read CSV files.
data = pd.read_csv(filename)
Step 4: Preprocess data
Obtain the feature variable and target variables
The target variable refers to the actual result predicted by the model, and the feature variables refer to variables other than the target variable in each instance data. In this example, the target variable is class, and the feature variables are sex, race, and age.
class: whether the annual income exceeds 50K
sex: gender
race: race
age: age
Run the following script to read data to the X_raw
and view part of the sample data:
# Obtain the feature variables, excluding the target variable.
X_raw = data.data
# Display the first five rows of data of the feature variables, excluding the target variable.
X_raw.head(5)
Run the following script to configure the value of the target variable and view part of the sample data. A value of 1 indicates an income greater than 50K. A value of 0 indicates an income less than or equal to 50K.
from sklearn.preprocessing import LabelEncoder
# Convert the target variable to a binary classification target.
# data.target is the target variable class.
y_true = (data.target == '>50K') * 1
y_true = LabelEncoder().fit_transform(y_true)
import matplotlib.pyplot as plt
import numpy as np
# View the distribution of the target variable.
counts = np.bincount(y_true)
classes = ['<=50K', '>50K']
plt.bar(classes, counts)
Obtain sensitive features
Run the following script to specify sex and race as sensitive features and view part of the sample data. This way, the responsible-ai-toolbox evaluates whether the inference results of the model are biased due to the two sensitive features. In actual scenarios, you can configure sensitive features based on your business requirements.
# Specify sex and race as sensitive information.
# Select the columns related to sensitive information from the dataset to form a new DataFrame named `sensitive_features`
sensitive_features = X_raw[['sex','race']]
sensitive_features.head(5)
Run the following script to delete sensitive features and data from X_raw
, and view the sample data after deletion.
# Remove sensitive features from feature variables.
X = X_raw.drop(labels=['sex', 'race'],axis = 1)
X.head(5)
Feature coding and standardization
Run the following script to standardize the data and convert the data into a format suitable for responsible-ai-toolbox.
import pandas as pd
from sklearn.preprocessing import StandardScaler
One-hot encoding
X = pd.get_dummies(X)
# Standardize the feature variables of dataset X
sc = StandardScaler()
X_scaled = sc.fit_transform(X)
X_scaled = pd.DataFrame(X_scaled, columns=X.columns)
X_scaled.head(5)
Split training and test data
Run the following script to split 20% of the data as the test dataset. The remaining data is used as the training dataset.
from sklearn.model_selection import train_test_split
# Split the feature variable X and target variable y to training and testing datasets based on the ratio `test_size`.
X_train, X_test, y_train, y_test = \
train_test_split(X_scaled, y_true, test_size=0.2, random_state=0, stratify=y_true)
# Split the sensitive features to training and testing datasets by using the same random seed. Make sure that the split ratio is the same as the previous step.
sensitive_features_train, sensitive_features_test = \
train_test_split(sensitive_features, test_size=0.2, random_state=0, stratify=y_true)
Check the data size of the training and test dataset.
print("Size of the training dataset:", len(X_train))
print("Size of the test dataset:", len(X_test))
Reset the index of the training and test dataset.
# Reset the index of DataFrame to prevent index error.
X_train = X_train.reset_index(drop=True)
sensitive_features_train = sensitive_features_train.reset_index(drop=True)
X_test = X_test.reset_index(drop=True)
sensitive_features_test = sensitive_features_test.reset_index(drop=True)
Step 5: Train the model
In this example, SkLearn is used to train a logistic regression model based on the training data.
Sklearn
from sklearn.linear_model import LogisticRegression
# Create a logistic regression model.
sk_model = LogisticRegression(solver='liblinear', fit_intercept=True)
# Train the model.
sk_model.fit(X_train, y_train)
PyTorch
import torch
import torch.nn as nn
import torch.optim as optim
# Define the logistic regression model.
class LogisticRegression(nn.Module):
def __init__(self, input_size):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, 1)
def forward(self, x):
outputs = torch.sigmoid(self.linear(x))
return outputs
# Instantiate the model.
input_size = X_train.shape[1]
pt_model = LogisticRegression(input_size)
# Loss functions and optimizer.
criterion = nn.BCELoss()
optimizer = optim.SGD(pt_model.parameters(), lr=5e-5)
# Train the model.
num_epochs = 1
X_train_pt = X_train
y_train_pt = y_train
for epoch in range(num_epochs):
# Forward propagation.
# Convert DataFrame to tensor.
if isinstance(X_train_pt, pd.DataFrame):
X_train_pt = torch.tensor(X_train_pt.values)
X_train_pt = X_train_pt.float()
outputs = pt_model(X_train_pt)
outputs = outputs.squeeze()
# Convert ndarray to tensor.
if isinstance(y_train_pt, np.ndarray):
y_train_pt = torch.from_numpy(y_train_pt)
y_train_pt = y_train_pt.float()
loss = criterion(outputs, y_train_pt)
# Back propagation and optimization.
optimizer.zero_grad()
loss.backward()
optimizer.step()
TensorFlow
import tensorflow as tf
from tensorflow.keras import layers
# Define the logistic regression model
tf_model = tf.keras.Sequential([
layers.Dense(units=1, input_shape=(X_train.shape[-1],), activation='sigmoid')
])
# Compile the model by using binary cross-entropy loss and stochastic gradient descent optimizer.
tf_model.compile(optimizer='sgd', loss='binary_crossentropy', metrics=['accuracy'])
# Train the model.
tf_model.fit(X_train, y_train, epochs=1, batch_size=32, verbose=0)
Step 6: Evaluate the model
Introduce FairnessDashboard and use responsible-ai-toolbox to predict results based on the test data and generate fairness evaluation reports.
The FairnessDashboard classifies prediction results and actual results based on sensitive variables, and conducts comparative analysis of prediction results and actual results to evaluate the model prediction based on different sensitive variables.
For example, sex is used as a sensitive feature. FairnessDashboard classifies the corresponding prediction results (y_pred) and actual results (y_test) based on sex, and calculates selection rate, accuracy, and other information for Male and Female in the sex category respectively for comparison.
In this example, run the following script to evaluate the model:
Sklearn
from raiwidgets import FairnessDashboard
import os
from urllib.parse import urlparse
# Predict results based on the test dataset.
y_pred_sk = sk_model.predict(X_test)
# Use responsible-ai-toolbox to calculate data information for each sensitive group.
metric_frame_sk = FairnessDashboard(sensitive_features=sensitive_features_test,
y_true=y_test,
y_pred=y_pred_sk, locale = 'zh-Hans')
# Specify the URL link.
metric_frame_sk.config['baseUrl'] = 'https://{}-proxy-{}.dsw-gateway-{}.data.aliyun.com'.format(
os.environ.get('JUPYTER_NAME').replace("dsw-",""),
urlparse(metric_frame_sk.config['baseUrl']).port,
os.environ.get('dsw_region') )
print(metric_frame_sk.config['baseUrl'])
PyTorch
from raiwidgets import FairnessDashboard
import torch
import os
from urllib.parse import urlparse
# Test the model and evaluate model fairness.
pt_model.eval() # Set the model to the evaluation mode.
X_test_pt = X_test
with torch.no_grad():
X_test_pt = torch.tensor(X_test_pt.values)
X_test_pt = X_test_pt.float()
y_pred_pt = pt_model(X_test_pt).numpy()
# Use responsible-ai-toolbox to calculate data information for each sensitive group.
metric_frame_pt = FairnessDashboard(sensitive_features=sensitive_features_test,
y_true=y_test,
y_pred=y_pred_pt.flatten().round(),locale='zh-Hans')
# Specify the URL link.
metric_frame_pt.config['baseUrl'] = 'https://{}-proxy-{}.dsw-gateway-{}.data.aliyun.com'.format(
os.environ.get('JUPYTER_NAME').replace("dsw-",""),
urlparse(metric_frame_pt.config['baseUrl']).port,
os.environ.get('dsw_region') )
print(metric_frame_pt.config['baseUrl'])
TensorFlow
from raiwidgets import FairnessDashboard
import os
from urllib.parse import urlparse
# Test the model and evaluate model fairness.
y_pred_tf = tf_model.predict(X_test).flatten()
# Use responsible-ai-toolbox to calculate data information for each sensitive group.
metric_frame_tf = FairnessDashboard(
sensitive_features=sensitive_features_test,
y_true=y_test,
y_pred=y_pred_tf.round(),locale='zh-Hans')
# Specify the URL link.
metric_frame_tf.config['baseUrl'] = 'https://{}-proxy-{}.dsw-gateway-{}.data.aliyun.com'.format(
os.environ.get('JUPYTER_NAME').replace("dsw-",""),
urlparse(metric_frame_tf.config['baseUrl']).port,
os.environ.get('dsw_region') )
print(metric_frame_tf.config['baseUrl'])
Parameters:
sensitive_features: the sensitive features.
y_true: the actual results generated by the training dataset.
y_pred: the predicted result of the model.
locale: Optional. The display language of the evaluation panel. Valid values: Simplified Chinese (zh-Hans), Traditional Chinese (zh-Hant), and English (en). Default value: en.
Step 7: View the evaluation report
After the evaluation is completed, click the URL to view the complete evaluation report.
On the FairnessDashboard page, click Get Started. Configure the sensitive features, performance metrics, and fairness metrics in sequence based on the following parameters to view the difference in metric data of the model.
Sensitive feature: sex
Sensitive feature: sex
Performance metric: accuracy
Fairness metrics: Demographic parity difference
Accuracy: the proportion of correctly predicted samples to the total number of samples. The accuracy of the model prediction on the annual income for males (81.6%) is less than the accuracy on the annual income for females (93.1%). However, both accuracies are relatively close to the overall accuracy of the model (85.4%).
Selection rate: the probability that the model generates the target variable as expected. In this case, the expected target variable is an annual income of more than 50K. The selection rate of the model prediction on males that have an annual income of more than 50K (25.7%) is greater than the prediction on females that have an annual income of more than 50K (7.36%). The selection rate of females that have an annual income of more than 50K (7.36%) is much less than the overall selection rate of the model (19.6%).
Demographic parity difference: the difference in the probability of positive prediction results between different protected groups under a given sensitive attribute. A value closer to 0 indicates a smaller bias between groups. The overall demographic parity difference of the model is 18.3%.
Sensitive feature: race
Sensitive feature: race
Performance metric: accuracy
Fairness metrics: Demographic parity difference
Accuracy: the proportion of correctly predicted samples to the total number of samples. The accuracy of the model prediction on the annual income for White and Asian-Pac-Islander individuals (84.9% and 79.1%) is lower than the accuracy for Black, Other, and Amer-Indian-Eskimo individuals (90.9%, 90.8%, and 91.9%). However, the accuracies for all sensitive feature groups are relatively close to the overall accuracy of the model (85.4%).
Selection rate: the probability that the model generates the target variable as expected. In this case, the expected target variable is an annual income of more than 50K. The selection rate for White and Asian-Pac-Islander individuals (21% and 23.9%) is greater than that for Black, Other, and Amer-Indian-Eskimo individuals (8.34%, 10.3%, and 8.14%). The selection rate for Black, Other, and Amer-Indian-Eskimo individuals (8.34%, 10.3%, and 8.14%) is much less than the overall selection rate of the model (19.6%).
Demographic parity difference: the difference in the probability of positive prediction results between different protected groups under a given sensitive attribute. A value closer to 0 indicates a smaller bias between groups. The overall demographic parity difference of the model is 18.3%.