{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# AI Automation for AI Fairness\n", "\n", "When AI models contribute to high-impact decisions such as whether or\n", "not someone gets a loan, we want them to be fair.\n", "Unfortunately, in current practice, AI models are often optimized\n", "primarily for accuracy, with little consideration for fairness. This\n", "blog post gives a hands-on example for how AI Automation can help build AI\n", "models that are both accurate and fair.\n", "This blog post is written for data scientists who have some familiarity\n", "with Python. No prior knowledge of AI Automation or AI Fairness is\n", "required, we will introduce the relevant concepts as we get to them.\n", "\n", "Bias in data leads to bias in models. AI models are increasingly\n", "consulted for consequential decisions about people, in domains\n", "including credit loans, hiring and retention, penal justice, medical,\n", "and more. Often, the model is trained from past decisions made by\n", "humans. If the decisions used for training were discriminatory, then\n", "your trained model will be too, unless you are careful. Being careful\n", "about bias is something you should do as a data scientist.\n", "Fortunately, you do not have to grapple with this issue alone. You\n", "can consult others about ethics. You can also ask yourself how your AI\n", "model may affect your (or your institution's) reputation. And\n", "ultimately, you must follow applicable laws and regulations.\n", "\n", "_AI Fairness_ can be measured via several metrics, and you need to\n", "select the appropriate metrics based on the circumstances. For\n", "illustration purposes, this blog post uses one particular fairness\n", "metric called _disparate impact_. Disparate impact is defined as the\n", "ratio of the rate of favorable outcome for the unprivileged group to\n", "that of the privileged group. To make this definition more concrete,\n", "consider the case where a favorable outcome means getting a loan, the\n", "unprivileged group is women, and the privileged group is men. Then if\n", "your AI model were to let women get a loan in 30% of the cases and men\n", "in 60% of the cases, the disparate impact would be 30% / 60% = 0.5,\n", "indicating a gender bias towards men. The ideal value for disparate\n", "impact is 1, and you could define fairness for this metric as a band\n", "around 1, e.g., from 0.8 to 1.2.\n", "\n", "To get the best performance out of your AI model, you must experiment\n", "with its configuration. This means searching a high-dimensional space\n", "where some options are categorical, some are continuous, and some are\n", "even conditional. No configuration is optimal for all domains let\n", "alone all metrics, and searching them all by hand is impossible. In\n", "fact, in a high-dimensional space, even exhaustively enumerating all\n", "the valid combinations soon becomes impractical. Fortunately, you can\n", "use tools to automate the search, thus making you more productive at\n", "finding good models quickly. These productivity and quality\n", "improvements become compounded when you have to do the search over.\n", "\n", "_AI Automation_ is a technology that assists data scientists in\n", "building AI models by automating some of the tedious steps. One AI\n", "automation technique is _algorithm selection_ , which automatically\n", "chooses among alternative algorithms for a particular task. Another AI\n", "automation technique is _hyperparameter tuning_ , which automatically\n", "configures the arguments of AI algorithms. You can use AI automation\n", "to optimize for a variety of metrics. This blog post shows you how to use AI\n", "automation to optimize for both accuracy and for fairness as measured\n", "by disparate impact.\n", "\n", "This blog post is generated from a [Jupyter](https://jupyter.org/)\n", "notebook that uses the following open-source Python libraries. \n", "[AIF360](https://aif360.mybluemix.net/) \n", "is a collection of fairness metrics and bias mitigation algorithms.\n", "The [pandas](https://pandas.pydata.org/),\n", "[scikit-learn](https://scikit-learn.org/), and\n", "[XGBoost](https://xgboost.ai/) libraries support\n", "data analysis and machine learning with data structures and a\n", "comprehensive collection of AI algorithms.\n", "The [hyperopt](http://hyperopt.github.io/hyperopt/) library\n", "implements both algorithm selection and hyperparameter tuning for\n", "AI automation.\n", "And [Lale](https://github.com/IBM/lale) is a library for\n", "semi-automated data science; this blog post uses Lale as the backbone\n", "for putting the other libraries together.\n", "\n", "Our starting point is a dataset and a task. For illustration\n", "purposes, we picked [credit-g](https://www.openml.org/d/31), also\n", "known as the German Credit dataset. Each row describes a person\n", "using several features that may help evaluate them as a potential\n", "loan applicant. The task is to classify people into either\n", "good or bad credit risks. We load a version of the dataset prepared\n", "for AIF360." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from lale.lib.aif360 import fetch_creditg_df\n", "(train_X, train_y), (test_X, test_y) = fetch_creditg_df()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To see what the dataset looks like, we can use off-the-shelf\n", "functionality from pandas for inspecting the shape and the first few\n", "rows. The creditg dataset has a single label column, `class`, to be\n", "predicted as the outcome.\n", "A _protected attribute_ is a feature that partitions the population\n", "into groups whose outcome should have parity. The credit-g dataset has\n", "two protected attribute columns, `sex` and `age`." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "train_X.shape (670, 58)\n" ] }, { "data": { "text/html": [ "
\n", " | class | \n", "checking_status_0<=X<200 | \n", "checking_status_<0 | \n", "checking_status_>=200 | \n", "checking_status_no checking | \n", "credit_history_all paid | \n", "credit_history_critical/other existing credit | \n", "credit_history_delayed previously | \n", "credit_history_existing paid | \n", "credit_history_no credits/all paid | \n", "purpose_business | \n", "purpose_domestic appliance | \n", "purpose_education | \n", "purpose_furniture/equipment | \n", "purpose_new car | \n", "purpose_other | \n", "purpose_radio/tv | \n", "purpose_repairs | \n", "purpose_retraining | \n", "purpose_used car | \n", "savings_status_100<=X<500 | \n", "savings_status_500<=X<1000 | \n", "savings_status_<100 | \n", "savings_status_>=1000 | \n", "savings_status_no known savings | \n", "employment_1<=X<4 | \n", "employment_4<=X<7 | \n", "employment_<1 | \n", "employment_>=7 | \n", "employment_unemployed | \n", "other_parties_co applicant | \n", "other_parties_guarantor | \n", "other_parties_none | \n", "property_magnitude_car | \n", "property_magnitude_life insurance | \n", "property_magnitude_no known property | \n", "property_magnitude_real estate | \n", "other_payment_plans_bank | \n", "other_payment_plans_none | \n", "other_payment_plans_stores | \n", "housing_for free | \n", "housing_own | \n", "housing_rent | \n", "job_high qualif/self emp/mgmt | \n", "job_skilled | \n", "job_unemp/unskilled non res | \n", "job_unskilled resident | \n", "own_telephone_none | \n", "own_telephone_yes | \n", "foreign_worker_no | \n", "foreign_worker_yes | \n", "duration | \n", "credit_amount | \n", "installment_commitment | \n", "residence_since | \n", "age | \n", "existing_credits | \n", "num_dependents | \n", "sex | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
863 | \n", "1 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "27.0 | \n", "4526.0 | \n", "4.0 | \n", "2.0 | \n", "1.0 | \n", "2.0 | \n", "2.0 | \n", "1.0 | \n", "
748 | \n", "1 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "21.0 | \n", "5248.0 | \n", "1.0 | \n", "3.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "
64 | \n", "1 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "24.0 | \n", "3181.0 | \n", "4.0 | \n", "4.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "
798 | \n", "1 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "24.0 | \n", "717.0 | \n", "4.0 | \n", "4.0 | \n", "1.0 | \n", "2.0 | \n", "1.0 | \n", "1.0 | \n", "
52 | \n", "1 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "12.0 | \n", "1262.0 | \n", "3.0 | \n", "2.0 | \n", "0.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "
440 | \n", "1 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "12.0 | \n", "1884.0 | \n", "4.0 | \n", "4.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "
124 | \n", "0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "18.0 | \n", "1924.0 | \n", "4.0 | \n", "3.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "
650 | \n", "1 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "48.0 | \n", "7476.0 | \n", "4.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "1.0 | \n", "
409 | \n", "0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "12.0 | \n", "939.0 | \n", "4.0 | \n", "2.0 | \n", "1.0 | \n", "3.0 | \n", "1.0 | \n", "1.0 | \n", "
752 | \n", "1 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "0.0 | \n", "1.0 | \n", "12.0 | \n", "841.0 | \n", "2.0 | \n", "4.0 | \n", "0.0 | \n", "1.0 | \n", "1.0 | \n", "0.0 | \n", "